solidus_reviews 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +18 -0
  5. data/CONTRIBUTING.md +28 -0
  6. data/Gemfile +14 -0
  7. data/LICENSE.md +26 -0
  8. data/README.md +93 -0
  9. data/Rakefile +21 -0
  10. data/app/assets/images/store/reviews/delete.gif +0 -0
  11. data/app/assets/images/store/reviews/star.gif +0 -0
  12. data/app/assets/javascripts/spree/backend/solidus_reviews.js +7 -0
  13. data/app/assets/javascripts/spree/frontend/solidus_reviews.js +7 -0
  14. data/app/assets/stylesheets/spree/backend/solidus_reviews.css +3 -0
  15. data/app/assets/stylesheets/spree/frontend/solidus_reviews.scss +83 -0
  16. data/app/controllers/spree/admin/feedback_reviews_controller.rb +6 -0
  17. data/app/controllers/spree/admin/review_settings_controller.rb +21 -0
  18. data/app/controllers/spree/admin/reviews_controller.rb +34 -0
  19. data/app/controllers/spree/feedback_reviews_controller.rb +41 -0
  20. data/app/controllers/spree/products_controller_decorator.rb +5 -0
  21. data/app/controllers/spree/reviews_controller.rb +48 -0
  22. data/app/helpers/spree/reviews_helper.rb +17 -0
  23. data/app/models/spree/feedback_review.rb +17 -0
  24. data/app/models/spree/product_decorator.rb +21 -0
  25. data/app/models/spree/review.rb +36 -0
  26. data/app/models/spree/reviews_ability.rb +17 -0
  27. data/app/models/spree/reviews_configuration.rb +26 -0
  28. data/app/overrides/add_reviews_after_product_properties.rb +5 -0
  29. data/app/overrides/add_reviews_tab_to_admin.rb +4 -0
  30. data/app/overrides/add_reviews_to_admin_configuration_sidebar.rb +5 -0
  31. data/app/views/spree/admin/feedback_reviews/index.html.erb +44 -0
  32. data/app/views/spree/admin/review_settings/edit.html.erb +40 -0
  33. data/app/views/spree/admin/reviews/_form.html.erb +22 -0
  34. data/app/views/spree/admin/reviews/edit.html.erb +26 -0
  35. data/app/views/spree/admin/reviews/index.html.erb +111 -0
  36. data/app/views/spree/feedback_reviews/_form.html.erb +13 -0
  37. data/app/views/spree/feedback_reviews/_summary.html.erb +6 -0
  38. data/app/views/spree/feedback_reviews/create.js.erb +7 -0
  39. data/app/views/spree/reviews/_form.html.erb +34 -0
  40. data/app/views/spree/reviews/_stars.html.erb +13 -0
  41. data/app/views/spree/reviews/index.html.erb +1 -0
  42. data/app/views/spree/reviews/new.html.erb +3 -0
  43. data/app/views/spree/shared/_rating.html.erb +15 -0
  44. data/app/views/spree/shared/_review.html.erb +28 -0
  45. data/app/views/spree/shared/_review_summary.html.erb +9 -0
  46. data/app/views/spree/shared/_reviews.html.erb +15 -0
  47. data/app/views/spree/shared/_shortrating.html.erb +9 -0
  48. data/bin/rails +5 -0
  49. data/config/initializers/constants.rb +1 -0
  50. data/config/initializers/load_preferences.rb +5 -0
  51. data/config/locales/de-CH.yml +68 -0
  52. data/config/locales/de.yml +68 -0
  53. data/config/locales/en-GB.yml +68 -0
  54. data/config/locales/en.yml +67 -0
  55. data/config/locales/es.yml +68 -0
  56. data/config/locales/fr.yml +68 -0
  57. data/config/locales/pl.yml +72 -0
  58. data/config/locales/pt-BR.yml +68 -0
  59. data/config/locales/pt.yml +69 -0
  60. data/config/locales/ro.yml +76 -0
  61. data/config/locales/ru.yml +73 -0
  62. data/config/locales/sv.yml +66 -0
  63. data/config/locales/tr.yml +68 -0
  64. data/config/locales/uk.yml +75 -0
  65. data/config/locales/zh-CN.yml +65 -0
  66. data/config/locales/zh-TW.yml +65 -0
  67. data/config/routes.rb +17 -0
  68. data/db/migrate/20081020220724_create_reviews.rb +18 -0
  69. data/db/migrate/20101222083309_create_feedback_reviews.rb +17 -0
  70. data/db/migrate/20110406083603_add_rating_to_products.rb +21 -0
  71. data/db/migrate/20110606150524_add_user_to_reviews.rb +9 -0
  72. data/db/migrate/20110806093221_add_ip_address_to_reviews.rb +9 -0
  73. data/db/migrate/20120110172331_namespace_tables.rb +6 -0
  74. data/db/migrate/20120123141326_recalculate_ratings.rb +20 -0
  75. data/db/migrate/20120712182514_add_locale_to_reviews.rb +9 -0
  76. data/db/migrate/20120712182627_add_locale_to_feedback_reviews.rb +9 -0
  77. data/db/migrate/20140703200946_add_show_identifier_to_reviews.rb +6 -0
  78. data/db/sample/ratings.yml +16 -0
  79. data/db/sample/reviews.yml +59 -0
  80. data/lib/generators/solidus_reviews/install/install_generator.rb +30 -0
  81. data/lib/solidus_reviews/factories/feedback_review_factory.rb +8 -0
  82. data/lib/solidus_reviews/factories/review_factory.rb +20 -0
  83. data/lib/solidus_reviews/factories.rb +5 -0
  84. data/lib/solidus_reviews.rb +6 -0
  85. data/lib/spree_reviews/engine.rb +17 -0
  86. data/solidus_reviews.gemspec +35 -0
  87. data/spec/controllers/admin/feedback_reviews_controller_spec.rb +29 -0
  88. data/spec/controllers/admin/review_settings_controller_spec.rb +57 -0
  89. data/spec/controllers/admin/reviews_controller_spec.rb +63 -0
  90. data/spec/controllers/feedback_reviews_controller_spec.rb +71 -0
  91. data/spec/controllers/products_controller_spec.rb +9 -0
  92. data/spec/controllers/reviews_controller_spec.rb +136 -0
  93. data/spec/features/admin_spec.rb +35 -0
  94. data/spec/features/reviews_spec.rb +122 -0
  95. data/spec/helpers/review_helper_spec.rb +28 -0
  96. data/spec/models/feedback_review_spec.rb +78 -0
  97. data/spec/models/product_spec.rb +62 -0
  98. data/spec/models/review_spec.rb +168 -0
  99. data/spec/models/reviews_ability_spec.rb +46 -0
  100. data/spec/models/reviews_configuration_spec.rb +45 -0
  101. data/spec/spec_helper.rb +55 -0
  102. data/vendor/assets/javascripts/jquery.rating.js +376 -0
  103. metadata +357 -0
@@ -0,0 +1,57 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Admin::ReviewSettingsController do
4
+ stub_authorization!
5
+
6
+ before do
7
+ user = create(:admin_user)
8
+ controller.stub(:try_spree_current_user => user)
9
+ end
10
+
11
+ context '#update' do
12
+ it 'redirects to edit-review-settings page' do
13
+ spree_put :update, preferences: { preview_size: 4 }
14
+ response.should redirect_to spree.edit_admin_review_settings_path
15
+ end
16
+
17
+ context 'For parameters:
18
+ preview_size: 4,
19
+ show_email: false,
20
+ feedback_rating: false,
21
+ require_login: true,
22
+ track_locale: true' do
23
+
24
+ it 'sets preferred_preview_size to 4' do
25
+ spree_put :update, preferences: { preview_size: 4 }
26
+ Spree::Reviews::Config.preferred_preview_size.should eq 4
27
+ end
28
+
29
+ it 'sets preferred_show_email to false' do
30
+ spree_put :update, preferences: { show_email: false }
31
+ Spree::Reviews::Config.preferred_show_email.should be false
32
+ end
33
+
34
+ it 'sets preferred_feedback_rating to false' do
35
+ spree_put :update, preferences: { feedback_rating: false }
36
+ Spree::Reviews::Config.preferred_feedback_rating.should be false
37
+ end
38
+
39
+ it 'sets preferred_require_login to true' do
40
+ spree_put :update, preferences: { require_login: true }
41
+ Spree::Reviews::Config.preferred_require_login.should be true
42
+ end
43
+
44
+ it 'sets preferred_track_locale to true' do
45
+ spree_put :update, preferences: { track_locale: true }
46
+ Spree::Reviews::Config.preferred_track_locale.should be true
47
+ end
48
+ end
49
+ end
50
+
51
+ context '#edit' do
52
+ it 'should render the edit template' do
53
+ spree_get :edit
54
+ response.should render_template(:edit)
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,63 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Admin::ReviewsController do
4
+ stub_authorization!
5
+
6
+ let(:product) { create(:product) }
7
+ let(:review) { create(:review, approved: false) }
8
+
9
+ before do
10
+ user = create(:admin_user)
11
+ controller.stub(try_spree_current_user: user)
12
+ end
13
+
14
+ context '#index' do
15
+ it 'list reviews' do
16
+ reviews = [
17
+ create(:review, product: product),
18
+ create(:review, product: product)
19
+ ]
20
+ spree_get :index, product_id: product.slug
21
+ assigns[:reviews].should =~ reviews
22
+ end
23
+ end
24
+
25
+ context '#approve' do
26
+ it 'show notice message when approved' do
27
+ review.update_attribute(:approved, true)
28
+ spree_get :approve, id: review.id
29
+ response.should redirect_to spree.admin_reviews_path
30
+ flash[:notice].should eq Spree.t(:info_approve_review)
31
+ end
32
+
33
+ it 'show error message when not approved' do
34
+ Spree::Review.any_instance.stub(:update_attribute).and_return(false)
35
+ spree_get :approve, id: review.id
36
+ flash[:error].should eq Spree.t(:error_approve_review)
37
+ end
38
+ end
39
+
40
+ context '#edit' do
41
+ specify do
42
+ spree_get :edit, id: review.id
43
+ response.status.should eq(200)
44
+ end
45
+
46
+ context 'when product is nil' do
47
+ before do
48
+ review.product = nil
49
+ review.save!
50
+ end
51
+
52
+ it 'flash error' do
53
+ spree_get :edit, id: review.id
54
+ flash[:error].should eq Spree.t(:error_no_product)
55
+ end
56
+
57
+ it 'redirect to admin-reviews page' do
58
+ spree_get :edit, id: review.id
59
+ response.should redirect_to spree.admin_reviews_path
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,71 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::FeedbackReviewsController do
4
+ let(:user) { create(:user) }
5
+ let(:product) { create(:product) }
6
+ let(:review) { create(:review, user: user) }
7
+ let(:valid_attributes) do
8
+ { review_id: review.id,
9
+ user_id: user.id,
10
+ feedback_review: {
11
+ rating: '4 stars',
12
+ comment: 'some comment'
13
+ }}
14
+ end
15
+
16
+ before do
17
+ controller.stub spree_current_user: user
18
+ controller.stub spree_user_signed_in?: true
19
+ request.env['HTTP_REFERER'] = '/'
20
+ end
21
+
22
+ describe '#create' do
23
+ it 'creates a new feedback review' do
24
+ rating = 4
25
+ comment = FFaker::Lorem.paragraphs(3).join("\n")
26
+ expect {
27
+ spree_post :create, { review_id: review.id,
28
+ feedback_review: { comment: comment,
29
+ rating: rating },
30
+ format: :js }
31
+ response.status.should eq(200)
32
+ response.should render_template(:create)
33
+ }.to change(Spree::Review, :count).by(1)
34
+ feedback_review = Spree::FeedbackReview.last
35
+ feedback_review.comment.should eq(comment)
36
+ feedback_review.review.should eq(review)
37
+ feedback_review.rating.should eq(rating)
38
+ feedback_review.user.should eq(user)
39
+
40
+ end
41
+
42
+ it 'redirects back to the calling page' do
43
+ spree_post :create, valid_attributes
44
+ response.should redirect_to '/'
45
+ end
46
+
47
+ it 'sets locale on feedback-review if required by config' do
48
+ Spree::Reviews::Config.preferred_track_locale = true
49
+ spree_post :create, valid_attributes
50
+ assigns[:review].locale.should eq I18n.locale.to_s
51
+ end
52
+
53
+ it 'fails when user is not authorized' do
54
+ controller.stub(:authorize!) { raise }
55
+ expect {
56
+ spree_post :create, valid_attributes
57
+ }.to raise_error
58
+ end
59
+
60
+ it 'removes all non-numbers from ratings parameter' do
61
+ spree_post :create, valid_attributes
62
+ controller.params[:feedback_review][:rating].should eq '4'
63
+ end
64
+
65
+ it 'do not create feedback-review if review doesnt exist' do
66
+ expect {
67
+ spree_post :create, valid_attributes.merge!({review_id: nil})
68
+ }.to raise_error
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::ProductsController do
4
+ [:avg_rating, :reviews_count].each do |attrib|
5
+ it "should add #{attrib} to the set of allowed attributes" do
6
+ controller.permitted_product_attributes.should include(attrib)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,136 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::ReviewsController, type: :controller do
4
+ let(:user) { create(:user) }
5
+ let(:product) { create(:product) }
6
+ let(:review_params) do
7
+ { product_id: product.slug,
8
+ review: { rating: 3,
9
+ name: 'Ryan Bigg',
10
+ title: 'Great Product',
11
+ review: 'Some big review text..' } }
12
+ end
13
+
14
+ before do
15
+ controller.stub :spree_current_user => user
16
+ controller.stub :spree_user_signed_in? => true
17
+ end
18
+
19
+ context '#index' do
20
+ context 'for a product that does not exist' do
21
+ it 'responds with a 404' do
22
+ spree_get :index, product_id: 'not_real'
23
+ response.status.should eq(404)
24
+ end
25
+ end
26
+
27
+ context 'for a valid product' do
28
+ it 'list approved reviews' do
29
+ approved_reviews = [
30
+ create(:review, :approved, product: product),
31
+ create(:review, :approved, product: product)
32
+ ]
33
+ spree_get :index, product_id: product.slug
34
+ assigns[:approved_reviews].should =~ approved_reviews
35
+ end
36
+ end
37
+ end
38
+
39
+ context '#new' do
40
+ context 'for a product that does not exist' do
41
+ it 'responds with a 404' do
42
+ spree_get :new, product_id: 'not_real'
43
+ response.status.should eq(404)
44
+ end
45
+ end
46
+
47
+ it 'fail if the user is not authorized to create a review' do
48
+ controller.stub(:authorize!) { raise }
49
+ expect {
50
+ spree_post :new, product_id: product.slug
51
+ assert_match 'ryanbig', response.body
52
+ }.to raise_error
53
+ end
54
+
55
+ it 'render the new template' do
56
+ spree_get :new, product_id: product.slug
57
+ response.status.should eq(200)
58
+ response.should render_template(:new)
59
+ end
60
+ end
61
+
62
+ context '#create' do
63
+ before { controller.stub spree_current_user: user }
64
+
65
+ context 'for a product that does not exist' do
66
+ it 'responds with a 404' do
67
+ spree_post :create, product_id: 'not_real'
68
+ response.status.should eq(404)
69
+ end
70
+ end
71
+
72
+ it 'creates a new review' do
73
+ expect {
74
+ spree_post :create, review_params
75
+ }.to change(Spree::Review, :count).by(1)
76
+ end
77
+
78
+ it 'sets the ip-address of the remote' do
79
+ request.stub(remote_ip: '127.0.0.1')
80
+ spree_post :create, review_params
81
+ assigns[:review].ip_address.should eq '127.0.0.1'
82
+ end
83
+
84
+ it 'fails if the user is not authorized to create a review' do
85
+ controller.stub(:authorize!) { raise }
86
+ expect{
87
+ spree_post :create, review_params
88
+ }.to raise_error
89
+ end
90
+
91
+ it 'flashes the notice' do
92
+ spree_post :create, review_params
93
+ flash[:notice].should eq Spree.t(:review_successfully_submitted)
94
+ end
95
+
96
+ it 'redirects to product page' do
97
+ spree_post :create, review_params
98
+ response.should redirect_to spree.product_path(product)
99
+ end
100
+
101
+ it 'removes all non-numbers from ratings param' do
102
+ spree_post :create, review_params
103
+ controller.params[:review][:rating].should eq '3'
104
+ end
105
+
106
+ it 'sets the current spree user as reviews user' do
107
+ spree_post :create, review_params
108
+ review_params[:review].merge!(user_id: user.id)
109
+ assigns[:review][:user_id] = user.id
110
+ assigns[:review][:user_id].should eq user.id
111
+ end
112
+
113
+ context 'with invalid params' do
114
+ it 'renders new when review.save fails' do
115
+ Spree::Review.any_instance.stub(:save).and_return(false)
116
+ spree_post :create, review_params
117
+ response.should render_template :new
118
+ end
119
+
120
+ it 'does not create a review' do
121
+ expect(Spree::Review.count).to eq 0
122
+ spree_post :create, review_params.merge({review: {rating: 'not_a_number'}})
123
+ expect(Spree::Review.count).to eq 0
124
+ end
125
+ end
126
+
127
+ # It always sets the locale so preference pointless
128
+ context 'when config requires locale tracking:' do
129
+ it 'sets the locale' do
130
+ Spree::Reviews::Config.preferred_track_locale = true
131
+ spree_post :create, review_params
132
+ assigns[:review].locale.should eq I18n.locale.to_s
133
+ end
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.feature 'Review Admin' do
4
+ stub_authorization!
5
+
6
+ given!(:review) { create(:review) }
7
+
8
+ context 'index' do
9
+ background do
10
+ visit spree.admin_reviews_path
11
+ end
12
+
13
+ scenario 'list reviews' do
14
+ expect(page).to have_text review.product.name
15
+ end
16
+
17
+ scenario 'approve reviews' do
18
+ expect(review.approved).to be false
19
+ within("tr#review_#{review.id}") do
20
+ find('.approve').click
21
+ end
22
+ expect(review.reload.approved).to be true
23
+ end
24
+
25
+ scenario 'edit reviews' do
26
+ expect(page).to have_text review.product.name
27
+ within("tr#review_#{review.id}") do
28
+ find('.edit').click
29
+ end
30
+
31
+ expect(page).to have_text 'Editing'
32
+ expect(page).to have_text review.title
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,122 @@
1
+ require 'spec_helper'
2
+
3
+ feature 'Reviews', js: true do
4
+ given!(:someone) { create(:user, email: 'ryan@spree.com') }
5
+ given!(:review) { create(:review, :approved, user: someone) }
6
+
7
+ background do
8
+ Spree::Reviews::Config.include_unapproved_reviews = false
9
+ end
10
+
11
+ context 'product with no review' do
12
+ given!(:product_no_reviews) { create(:product) }
13
+ scenario 'informs that no reviews has been written yet' do
14
+ visit spree.product_path(product_no_reviews)
15
+ expect(page).to have_text Spree.t(:no_reviews_available)
16
+ end
17
+
18
+ # Regression test for #103
19
+ context "shows correct number of previews" do
20
+ background do
21
+ FactoryGirl.create_list :review, 3, product: product_no_reviews, approved: true
22
+ Spree::Reviews::Config[:preview_size] = 2
23
+ end
24
+
25
+ scenario "displayed reviews are limited by the set preview size" do
26
+ visit spree.product_path(product_no_reviews)
27
+ expect(page.all(".review").count).to eql(2)
28
+ end
29
+ end
30
+ end
31
+
32
+ context 'when anonymous user' do
33
+ background do
34
+ Spree::Reviews::Config.require_login = true
35
+ end
36
+
37
+ context 'visit product with review' do
38
+ background do
39
+ visit spree.product_path(review.product)
40
+ end
41
+
42
+ scenario 'should see review title' do
43
+ expect(page).to have_text review.title
44
+ end
45
+
46
+ scenario 'can not create review' do
47
+ expect(page).not_to have_text Spree.t(:write_your_own_review)
48
+ end
49
+ end
50
+ end
51
+
52
+ context 'when logged in user' do
53
+ given!(:user) { create(:user) }
54
+
55
+ background do
56
+ sign_in_as! user
57
+ end
58
+
59
+ context 'visit product with review' do
60
+ background do
61
+ visit spree.product_path(review.product)
62
+ end
63
+
64
+ scenario 'can see review title' do
65
+ expect(page).to have_text review.title
66
+ end
67
+
68
+ scenario 'can see create new review button' do
69
+ expect(page).to have_text Spree.t(:write_your_own_review)
70
+ end
71
+
72
+ scenario 'can create new review' do
73
+ click_on Spree.t(:write_your_own_review)
74
+
75
+ expect(page).to have_text Spree.t(:leave_us_a_review_for, name: review.product.name)
76
+ expect(page).not_to have_text 'Show Identifier'
77
+
78
+ within '#new_review' do
79
+ click_star(3)
80
+
81
+ fill_in 'review_name', with: user.email
82
+ fill_in 'review_title', with: 'Great product!'
83
+ fill_in 'review_review', with: 'Some big review text..'
84
+ click_on 'Submit your review'
85
+ end
86
+
87
+ expect(page.find('.flash.notice', text: Spree.t(:review_successfully_submitted))).to be_truthy
88
+ expect(page).not_to have_text 'Some big review text..'
89
+ end
90
+ end
91
+ end
92
+
93
+ context 'visit product with review where show_identifier is false' do
94
+ given!(:user) { create(:user) }
95
+ given!(:review) { create(:review, :approved, :hide_identifier, review: 'review text', user: user) }
96
+
97
+ background do
98
+ visit spree.product_path(review.product)
99
+ end
100
+
101
+ scenario 'show anonymous review' do
102
+ expect(page).to have_text Spree.t(:anonymous)
103
+ expect(page).to have_text 'review text'
104
+ end
105
+
106
+ end
107
+
108
+ private
109
+
110
+ def sign_in_as!(user)
111
+ visit spree.login_path
112
+ within '#new_spree_user' do
113
+ fill_in 'Email', with: user.email
114
+ fill_in 'Password', with: user.password
115
+ end
116
+ click_button 'Login'
117
+ end
118
+
119
+ def click_star(num)
120
+ page.all(:xpath, "//a[@title='#{num} stars']")[0].click
121
+ end
122
+ end
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::ReviewsHelper do
4
+ context 'star' do
5
+ specify do
6
+ expect(star('a_class')).to eq '<span class="a_class"> &#10030; </span>'
7
+ end
8
+ end
9
+
10
+ context 'mk_stars' do
11
+ specify do
12
+ matches = mk_stars(2).scan(/unlit/)
13
+ expect(matches.length).to eq 3
14
+
15
+ end
16
+ end
17
+
18
+ context 'txt_stars' do
19
+ specify do
20
+ expect(txt_stars(2, true)).to eq '2 out of 5'
21
+ end
22
+
23
+ specify do
24
+ expect(txt_stars(3, false)).to be_a String
25
+ expect(txt_stars(3, false)).to eq('3')
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,78 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::FeedbackReview do
4
+ context 'validations' do
5
+ it 'validates by default' do
6
+ build(:feedback_review).should be_valid
7
+ end
8
+
9
+ it 'validates with a nil user' do
10
+ build(:feedback_review, user: nil).should be_valid
11
+ end
12
+
13
+ it 'does not validate with a nil review' do
14
+ build(:feedback_review, review: nil).should_not be_valid
15
+ end
16
+
17
+ context 'rating' do
18
+ it 'does not validate when no rating is specified' do
19
+ build(:feedback_review, rating: nil).should_not be_valid
20
+ end
21
+
22
+ it 'does not validate when the rating is not a number' do
23
+ build(:feedback_review, rating: 'not_a_number').should_not be_valid
24
+ end
25
+
26
+ it 'does not validate when the rating is a float' do
27
+ build(:feedback_review, rating: 2.718).should_not be_valid
28
+ end
29
+
30
+ it 'does not validate when the rating is less than 1' do
31
+ build(:feedback_review, rating: 0).should_not be_valid
32
+ build(:feedback_review, rating: -5).should_not be_valid
33
+ end
34
+
35
+ it 'does not validate when the rating is greater than 5' do
36
+ build(:feedback_review, rating: 6).should_not be_valid
37
+ build(:feedback_review, rating: 8).should_not be_valid
38
+ end
39
+
40
+ (1..5).each do |i|
41
+ it "validates when the rating is #{i}" do
42
+ build(:feedback_review, rating: i).should be_valid
43
+ end
44
+ end
45
+ end
46
+ end
47
+
48
+ context 'scopes' do
49
+ context 'most_recent_first' do
50
+ let!(:feedback_review_1) { create(:feedback_review, created_at: 10.days.ago) }
51
+ let!(:feedback_review_2) { create(:feedback_review, created_at: 2.days.ago) }
52
+ let!(:feedback_review_3) { create(:feedback_review, created_at: 5.days.ago) }
53
+
54
+ it 'properly runs most_recent_first queries' do
55
+ Spree::FeedbackReview.most_recent_first.to_a.should eq([feedback_review_2, feedback_review_3, feedback_review_1])
56
+ end
57
+
58
+ it 'defaults to most_recent_first queries' do
59
+ Spree::FeedbackReview.all.to_a.should eq([feedback_review_2, feedback_review_3, feedback_review_1])
60
+ end
61
+ end
62
+
63
+ context 'localized' do
64
+ let!(:en_feedback_review_1) { create(:feedback_review, locale: 'en', created_at: 10.days.ago) }
65
+ let!(:en_feedback_review_2) { create(:feedback_review, locale: 'en', created_at: 2.days.ago) }
66
+ let!(:en_feedback_review_3) { create(:feedback_review, locale: 'en', created_at: 5.days.ago) }
67
+
68
+ let!(:es_feedback_review_1) { create(:feedback_review, locale: 'es', created_at: 10.days.ago) }
69
+ let!(:fr_feedback_review_1) { create(:feedback_review, locale: 'fr', created_at: 10.days.ago) }
70
+
71
+ it 'properly runs localized queries' do
72
+ Spree::FeedbackReview.localized('en').to_a.should eq([en_feedback_review_2, en_feedback_review_3, en_feedback_review_1])
73
+ Spree::FeedbackReview.localized('es').to_a.should eq([es_feedback_review_1])
74
+ Spree::FeedbackReview.localized('fr').to_a.should eq([fr_feedback_review_1])
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,62 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Product do
4
+ it { should respond_to(:avg_rating) }
5
+ it { should respond_to(:reviews) }
6
+ it { should respond_to(:stars) }
7
+
8
+ context '#stars' do
9
+ let(:product) { build(:product) }
10
+
11
+ it 'rounds' do
12
+ product.stub(:avg_rating).and_return(3.7)
13
+ expect(product.stars).to eq(4)
14
+
15
+ product.stub(:avg_rating).and_return(2.3)
16
+ expect(product.stars).to eq(2)
17
+ end
18
+
19
+
20
+ it 'handles a nil value' do
21
+ product.stub(:avg_rating).and_return(nil)
22
+ expect {
23
+ expect(product.stars).to eq(0)
24
+ }.not_to raise_error
25
+ end
26
+ end
27
+
28
+ context '#recalculate_rating' do
29
+ let!(:product) { create(:product) }
30
+
31
+ context 'when there are approved reviews' do
32
+ let!(:approved_review_1) { create(:review, product: product, approved: true, rating: 4) }
33
+ let!(:approved_review_2) { create(:review, product: product, approved: true, rating: 5) }
34
+ let!(:unapproved_review_1) { create(:review, product: product, approved: false, rating: 4) }
35
+
36
+ it "updates the product average rating and ignores unapproved reviews" do
37
+ product.avg_rating = 0
38
+ product.reviews_count = 0
39
+ product.save!
40
+
41
+ product.recalculate_rating
42
+ product.avg_rating.should eq(4.5)
43
+ product.reviews_count.should eq(2)
44
+ end
45
+ end
46
+
47
+ context 'when no approved reviews' do
48
+ let!(:unapproved_review_1) { create(:review, product: product, approved: false, rating: 4) }
49
+
50
+ it "updates the product average rating and ignores unapproved reviews" do
51
+ product.avg_rating = 3
52
+ product.reviews_count = 20
53
+ product.save!
54
+
55
+ product.recalculate_rating
56
+ product.avg_rating.should eq(0)
57
+ product.reviews_count.should eq(0)
58
+ end
59
+ end
60
+
61
+ end
62
+ end