solidus_reviews 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. checksums.yaml +5 -5
  2. data/.rubocop.yml +322 -0
  3. data/.travis.yml +27 -14
  4. data/Gemfile +23 -8
  5. data/LICENSE.md +2 -2
  6. data/README.md +9 -11
  7. data/Rakefile +2 -0
  8. data/app/controllers/spree/admin/feedback_reviews_controller.rb +3 -1
  9. data/app/controllers/spree/admin/review_settings_controller.rb +3 -1
  10. data/app/controllers/spree/admin/reviews_controller.rb +9 -6
  11. data/app/controllers/spree/feedback_reviews_controller.rb +25 -19
  12. data/app/controllers/spree/products_controller_decorator.rb +2 -0
  13. data/app/controllers/spree/reviews_controller.rb +11 -7
  14. data/app/helpers/spree/api/api_helpers_decorator.rb +12 -0
  15. data/app/helpers/spree/reviews_helper.rb +15 -5
  16. data/app/models/spree/feedback_review.rb +5 -4
  17. data/app/models/spree/product_decorator.rb +5 -4
  18. data/app/models/spree/review.rb +28 -10
  19. data/app/models/spree/reviews_ability.rb +17 -3
  20. data/app/models/spree/reviews_configuration.rb +16 -8
  21. data/app/models/spree/user_decorator.rb +3 -0
  22. data/app/overrides/add_reviews_after_product_properties.rb +7 -5
  23. data/app/overrides/add_reviews_tab_to_admin.rb +12 -4
  24. data/app/overrides/add_reviews_to_admin_configuration_sidebar.rb +13 -5
  25. data/app/views/spree/admin/feedback_reviews/index.html.erb +9 -9
  26. data/app/views/spree/admin/review_settings/edit.html.erb +64 -35
  27. data/app/views/spree/admin/reviews/_form.html.erb +26 -5
  28. data/app/views/spree/admin/reviews/edit.html.erb +2 -2
  29. data/app/views/spree/admin/reviews/index.html.erb +100 -88
  30. data/app/views/spree/api/reviews/_review.json.jbuilder +8 -0
  31. data/app/views/spree/api/reviews/index.json.jbuilder +6 -0
  32. data/app/views/spree/api/reviews/show.json.jbuilder +3 -0
  33. data/app/views/spree/feedback_reviews/_form.html.erb +5 -5
  34. data/app/views/spree/feedback_reviews/_summary.html.erb +3 -3
  35. data/app/views/spree/feedback_reviews/create.js.erb +2 -2
  36. data/app/views/spree/reviews/_form.html.erb +15 -10
  37. data/app/views/spree/reviews/new.html.erb +2 -2
  38. data/app/views/spree/shared/_rating.html.erb +3 -3
  39. data/app/views/spree/shared/_review.html.erb +29 -19
  40. data/app/views/spree/shared/_review_summary.html.erb +3 -3
  41. data/app/views/spree/shared/_reviews.html.erb +6 -6
  42. data/app/views/spree/shared/_shortrating.html.erb +2 -2
  43. data/bin/rails +4 -2
  44. data/config/initializers/constants.rb +2 -0
  45. data/config/initializers/load_preferences.rb +2 -0
  46. data/config/locales/de-CH.yml +14 -1
  47. data/config/locales/de.yml +14 -1
  48. data/config/locales/en-GB.yml +14 -2
  49. data/config/locales/en.yml +14 -1
  50. data/config/locales/es.yml +14 -2
  51. data/config/locales/fr.yml +14 -2
  52. data/config/locales/it.yml +79 -0
  53. data/config/locales/pl.yml +14 -2
  54. data/config/locales/pt-BR.yml +14 -2
  55. data/config/locales/pt.yml +14 -2
  56. data/config/locales/ro.yml +15 -3
  57. data/config/locales/ru.yml +14 -2
  58. data/config/locales/sv.yml +14 -1
  59. data/config/locales/tr.yml +14 -2
  60. data/config/locales/uk.yml +14 -1
  61. data/config/locales/zh-CN.yml +14 -1
  62. data/config/locales/zh-TW.yml +14 -1
  63. data/config/routes.rb +18 -1
  64. data/db/migrate/20081020220724_create_reviews.rb +4 -2
  65. data/db/migrate/20101222083309_create_feedback_reviews.rb +5 -3
  66. data/db/migrate/20110406083603_add_rating_to_products.rb +7 -5
  67. data/db/migrate/20110606150524_add_user_to_reviews.rb +4 -2
  68. data/db/migrate/20110806093221_add_ip_address_to_reviews.rb +3 -1
  69. data/db/migrate/20120110172331_namespace_tables.rb +3 -1
  70. data/db/migrate/20120123141326_recalculate_ratings.rb +6 -5
  71. data/db/migrate/20120712182514_add_locale_to_reviews.rb +4 -2
  72. data/db/migrate/20120712182627_add_locale_to_feedback_reviews.rb +4 -2
  73. data/db/migrate/20140703200946_add_show_identifier_to_reviews.rb +3 -1
  74. data/db/migrate/20190613165528_add_verified_purchaser_to_reviews.rb +5 -0
  75. data/lib/controllers/spree/api/reviews_controller.rb +111 -0
  76. data/lib/generators/solidus_reviews/install/install_generator.rb +5 -4
  77. data/lib/solidus_reviews.rb +3 -1
  78. data/lib/solidus_reviews/factories.rb +3 -1
  79. data/lib/solidus_reviews/factories/feedback_review_factory.rb +6 -5
  80. data/lib/solidus_reviews/factories/review_factory.rb +19 -9
  81. data/lib/spree_reviews/engine.rb +7 -0
  82. data/solidus_reviews.gemspec +20 -18
  83. data/spec/controllers/admin/feedback_reviews_controller_spec.rb +9 -7
  84. data/spec/controllers/admin/review_settings_controller_spec.rb +18 -16
  85. data/spec/controllers/admin/reviews_controller_spec.rb +18 -16
  86. data/spec/controllers/feedback_reviews_controller_spec.rb +29 -25
  87. data/spec/controllers/products_controller_spec.rb +4 -2
  88. data/spec/controllers/reviews_controller_spec.rb +67 -40
  89. data/spec/controllers/spree/api/reviews_controller_spec.rb +233 -0
  90. data/spec/features/admin_spec.rb +3 -0
  91. data/spec/features/reviews_spec.rb +27 -11
  92. data/spec/helpers/review_helper_spec.rb +3 -2
  93. data/spec/models/feedback_review_spec.rb +19 -17
  94. data/spec/models/product_spec.rb +41 -19
  95. data/spec/models/review_spec.rb +100 -42
  96. data/spec/models/reviews_ability_spec.rb +10 -8
  97. data/spec/models/reviews_configuration_spec.rb +28 -19
  98. data/spec/spec_helper.rb +21 -35
  99. data/vendor/assets/javascripts/jquery.rating.js +389 -376
  100. metadata +108 -59
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Spree::ProductsController do
4
6
  [:avg_rating, :reviews_count].each do |attrib|
5
7
  it "should add #{attrib} to the set of allowed attributes" do
6
- controller.permitted_product_attributes.should include(attrib)
8
+ expect(controller.permitted_product_attributes).to include(attrib)
7
9
  end
8
10
  end
9
- end
11
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Spree::ReviewsController, type: :controller do
@@ -8,19 +10,24 @@ describe Spree::ReviewsController, type: :controller do
8
10
  review: { rating: 3,
9
11
  name: 'Ryan Bigg',
10
12
  title: 'Great Product',
11
- review: 'Some big review text..' } }
13
+ review: 'Some big review text..',
14
+ images: [
15
+ fixture_file_upload(File.new(Spree::Core::Engine.root + 'spec/fixtures/thinking-cat.jpg'))
16
+ ] }
17
+ }
12
18
  end
13
19
 
14
20
  before do
15
- controller.stub :spree_current_user => user
16
- controller.stub :spree_user_signed_in? => true
21
+ allow(controller).to receive(:spree_current_user).and_return(user)
22
+ allow(controller).to receive(:spree_user_signed_in?).and_return(true)
17
23
  end
18
24
 
19
25
  context '#index' do
20
26
  context 'for a product that does not exist' do
21
27
  it 'responds with a 404' do
22
- spree_get :index, product_id: 'not_real'
23
- response.status.should eq(404)
28
+ expect {
29
+ get :index, params: { product_id: 'not_real' }
30
+ }.to raise_error(ActiveRecord::RecordNotFound)
24
31
  end
25
32
  end
26
33
 
@@ -30,8 +37,8 @@ describe Spree::ReviewsController, type: :controller do
30
37
  create(:review, :approved, product: product),
31
38
  create(:review, :approved, product: product)
32
39
  ]
33
- spree_get :index, product_id: product.slug
34
- assigns[:approved_reviews].should =~ approved_reviews
40
+ get :index, params: { product_id: product.slug }
41
+ expect(assigns[:approved_reviews]).to match_array approved_reviews
35
42
  end
36
43
  end
37
44
  end
@@ -39,87 +46,107 @@ describe Spree::ReviewsController, type: :controller do
39
46
  context '#new' do
40
47
  context 'for a product that does not exist' do
41
48
  it 'responds with a 404' do
42
- spree_get :new, product_id: 'not_real'
43
- response.status.should eq(404)
49
+ expect {
50
+ get :new, params: { product_id: 'not_real' }
51
+ }.to raise_error(ActiveRecord::RecordNotFound)
44
52
  end
45
53
  end
46
54
 
47
55
  it 'fail if the user is not authorized to create a review' do
48
- controller.stub(:authorize!) { raise }
56
+ allow(controller).to receive(:authorize!).and_raise(RuntimeError)
57
+
49
58
  expect {
50
- spree_post :new, product_id: product.slug
59
+ post :new, params: { product_id: product.slug }
51
60
  assert_match 'ryanbig', response.body
52
- }.to raise_error
61
+ }.to raise_error RuntimeError
53
62
  end
54
63
 
55
64
  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)
65
+ get :new, params: { product_id: product.slug }
66
+ expect(response.status).to eq(200)
67
+ expect(response).to render_template(:new)
59
68
  end
60
69
  end
61
70
 
62
71
  context '#create' do
63
- before { controller.stub spree_current_user: user }
72
+ before { allow(controller).to receive(:spree_current_user).and_return(user) }
64
73
 
65
74
  context 'for a product that does not exist' do
66
75
  it 'responds with a 404' do
67
- spree_post :create, product_id: 'not_real'
68
- response.status.should eq(404)
76
+ expect {
77
+ post :create, params: { product_id: 'not_real' }
78
+ }.to raise_error(ActiveRecord::RecordNotFound)
69
79
  end
70
80
  end
71
81
 
72
82
  it 'creates a new review' do
73
83
  expect {
74
- spree_post :create, review_params
84
+ post :create, params: review_params
85
+ }.to change(Spree::Review, :count).by(1)
86
+ end
87
+
88
+ it 'creates a rating only review' do
89
+ review_params = {
90
+ product_id: product.slug,
91
+ review: { rating: 3 }
92
+ }
93
+
94
+ expect {
95
+ post :create, params: review_params
75
96
  }.to change(Spree::Review, :count).by(1)
76
97
  end
77
98
 
78
99
  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'
100
+ @request.env['REMOTE_ADDR'] = '127.0.0.1'
101
+ post :create, params: review_params
102
+ expect(assigns[:review].ip_address).to eq '127.0.0.1'
103
+ end
104
+
105
+ it 'attaches the image' do
106
+ post :create, params: review_params
107
+ expect(assigns[:review].images).to be_present
82
108
  end
83
109
 
84
110
  it 'fails if the user is not authorized to create a review' do
85
- controller.stub(:authorize!) { raise }
111
+ allow(controller).to receive(:authorize!).and_raise(RuntimeError)
112
+
86
113
  expect{
87
- spree_post :create, review_params
88
- }.to raise_error
114
+ post :create, params: review_params
115
+ }.to raise_error RuntimeError
89
116
  end
90
117
 
91
118
  it 'flashes the notice' do
92
- spree_post :create, review_params
93
- flash[:notice].should eq Spree.t(:review_successfully_submitted)
119
+ post :create, params: review_params
120
+ expect(flash[:notice]).to eq I18n.t('spree.review_successfully_submitted')
94
121
  end
95
122
 
96
123
  it 'redirects to product page' do
97
- spree_post :create, review_params
98
- response.should redirect_to spree.product_path(product)
124
+ post :create, params: review_params
125
+ expect(response).to redirect_to spree.product_path(product)
99
126
  end
100
127
 
101
128
  it 'removes all non-numbers from ratings param' do
102
- spree_post :create, review_params
103
- controller.params[:review][:rating].should eq '3'
129
+ post :create, params: review_params
130
+ expect(controller.params[:review][:rating]).to eq '3'
104
131
  end
105
132
 
106
133
  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)
134
+ post :create, params: review_params
135
+ review_params[:review][:user_id] = user.id
109
136
  assigns[:review][:user_id] = user.id
110
- assigns[:review][:user_id].should eq user.id
137
+ expect(assigns[:review][:user_id]).to eq user.id
111
138
  end
112
139
 
113
140
  context 'with invalid params' do
114
141
  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
142
+ expect_any_instance_of(Spree::Review).to receive(:save).and_return(false)
143
+ post :create, params: review_params
144
+ expect(response).to render_template :new
118
145
  end
119
146
 
120
147
  it 'does not create a review' do
121
148
  expect(Spree::Review.count).to eq 0
122
- spree_post :create, review_params.merge({review: {rating: 'not_a_number'}})
149
+ post :create, params: review_params.merge({ review: { rating: 'not_a_number' } })
123
150
  expect(Spree::Review.count).to eq 0
124
151
  end
125
152
  end
@@ -128,8 +155,8 @@ describe Spree::ReviewsController, type: :controller do
128
155
  context 'when config requires locale tracking:' do
129
156
  it 'sets the locale' do
130
157
  Spree::Reviews::Config.preferred_track_locale = true
131
- spree_post :create, review_params
132
- assigns[:review].locale.should eq I18n.locale.to_s
158
+ post :create, params: review_params
159
+ expect(assigns[:review].locale).to eq I18n.locale.to_s
133
160
  end
134
161
  end
135
162
  end
@@ -0,0 +1,233 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Spree::Api::ReviewsController, type: :controller do
6
+ render_views
7
+
8
+ let!(:user) { create(:user) }
9
+ let!(:review) { create(:review, rating: 5) }
10
+ let!(:product) { review.product }
11
+
12
+ before do
13
+ user.generate_spree_api_key!
14
+ Array.new(3).each do
15
+ create(:review)
16
+ end
17
+ end
18
+
19
+ describe '#index' do
20
+ context 'when given a product_id' do
21
+ subject do
22
+ get :index, params: { product_id: product.id, token: user.spree_api_key, format: 'json' }
23
+ JSON.parse(response.body)
24
+ end
25
+
26
+ context 'there are no reviews for a product' do
27
+ it 'should return an empty array' do
28
+ expect(Spree::Review.count).to be >= 0
29
+ expect(subject["reviews"]).to be_empty
30
+ end
31
+ end
32
+
33
+ context 'there are reviews for the product and other products' do
34
+ it 'returns all approved reviews for the product' do
35
+ review.update(approved: true)
36
+ review.images << create(:image)
37
+ expect(Spree::Review.count).to be >= 2
38
+ expect(subject.size).to eq(2)
39
+ expect(subject["reviews"][0]["id"]).to eq(review.id)
40
+ expect(subject["reviews"][0]["images"].count).to eq(1)
41
+ expect(subject["avg_rating"]).to eq("5.0")
42
+ end
43
+ end
44
+ end
45
+
46
+ context 'when given a user_id' do
47
+ subject do
48
+ get :index, params: { user_id: user.id, token: user.spree_api_key, format: 'json' }
49
+ JSON.parse(response.body)
50
+ end
51
+
52
+ context 'there are no reviews for the user' do
53
+ it 'should return an empty array' do
54
+ expect(Spree::Review.count).to be >= 0
55
+ expect(subject["reviews"]).to be_empty
56
+ end
57
+ end
58
+
59
+ context 'there are reviews for user' do
60
+ before { review.update(user_id: user.id) }
61
+
62
+ it 'returns all reviews for the user' do
63
+ expect(Spree::Review.count).to be >= 2
64
+ expect(subject.size).to eq(2)
65
+ expect(subject["reviews"][0]["id"]).to eq(review.id)
66
+ expect(subject["avg_rating"]).to eq(nil)
67
+ end
68
+ end
69
+ end
70
+ end
71
+
72
+ describe '#show' do
73
+ subject do
74
+ get :show, params: { id: review.id, token: user.spree_api_key, format: 'json' }
75
+ JSON.parse(response.body)
76
+ end
77
+
78
+ context 'when it is the users review' do
79
+ before { review.update(user_id: user.id) }
80
+
81
+ it 'should return the review' do
82
+ expect(subject).not_to be_empty
83
+ expect(subject["product_id"]).to eq(product.id)
84
+ expect(subject["name"]).to eq(review[:name])
85
+ expect(subject["review"]).to eq(review[:review])
86
+ expect(subject["title"]).to eq(review[:title])
87
+ expect(subject["verified_purchaser"]).to eq(false)
88
+ expect(subject["images"]).to eq([])
89
+ expect(subject["feedback_reviews"]).to eq([])
90
+ end
91
+ end
92
+
93
+ context 'when it is not the users review' do
94
+ it 'should return with not authorized' do
95
+ expect(subject["error"]).not_to be_empty
96
+ expect(subject["error"]).to match(/not authorized/i)
97
+ end
98
+
99
+ context 'and it the review is approved' do
100
+ before { review.update(approved: true) }
101
+
102
+ it 'should return the review' do
103
+ expect(subject).not_to be_empty
104
+ expect(subject["product_id"]).to eq(product.id)
105
+ expect(subject["name"]).to eq(review[:name])
106
+ expect(subject["review"]).to eq(review[:review])
107
+ expect(subject["title"]).to eq(review[:title])
108
+ expect(subject["images"]).to eq([])
109
+ expect(subject["feedback_reviews"]).to eq([])
110
+ end
111
+ end
112
+ end
113
+ end
114
+
115
+ describe '#create' do
116
+ let(:review_params) do
117
+ {
118
+ "user_id": user.id,
119
+ "rating": "3 stars",
120
+ "title": "My title 2",
121
+ "name": "Full Name",
122
+ "review": "My review of the product"
123
+ }
124
+ end
125
+
126
+ subject do
127
+ params = { product_id: product.id, token: user.spree_api_key, format: 'json' }.merge(review_params)
128
+ post :create, params: params
129
+ JSON.parse(response.body)
130
+ end
131
+
132
+ context 'when user has already reviewed this product' do
133
+ before do
134
+ review.update(user_id: user.id)
135
+ end
136
+
137
+ it 'should return with a fail' do
138
+ expect(subject["error"]).not_to be_empty
139
+ expect(subject["error"]).to match(/invalid resource/i)
140
+ end
141
+ end
142
+
143
+ context 'when it is a users first review for the product' do
144
+ it 'should return success with review' do
145
+ expect(subject).not_to be_empty
146
+ expect(subject["product_id"]).to eq(product.id)
147
+ expect(subject["name"]).to eq(review_params[:name])
148
+ expect(subject["review"]).to eq(review_params[:review])
149
+ expect(subject["title"]).to eq(review_params[:title])
150
+ expect(subject["images"]).to eq([])
151
+ expect(subject["feedback_reviews"]).to eq([])
152
+ end
153
+ end
154
+ end
155
+
156
+ describe '#update' do
157
+ before { review.update(approved: true, user_id: user.id) }
158
+ let(:params) { { product_id: product.id, id: review.id, token: user.spree_api_key, format: 'json' }.merge(review_params) }
159
+
160
+ let(:review_params) do
161
+ {
162
+ "rating": "3 stars",
163
+ "title": "My title 2",
164
+ "name": "Full name",
165
+ "review": "My review of the product",
166
+ }
167
+ end
168
+
169
+ subject do
170
+ put :update, params: params
171
+ JSON.parse(response.body)
172
+ end
173
+
174
+ context 'when a user updates their own review' do
175
+ it 'should successfully update the review and set approved back to false' do
176
+ original = review
177
+ expect(original.approved?).to be true
178
+ expect(subject["id"]).to eq(original.id)
179
+ expect(subject["user_id"]).to eq(original.user_id)
180
+ expect(subject["product_id"]).to eq(original.product_id)
181
+ expect(subject["approved"]).to be false
182
+ expect(subject["images"]).to eq([])
183
+ expect(subject["feedback_reviews"]).to eq([])
184
+ end
185
+ end
186
+
187
+ context 'when a user updates another users review' do
188
+ let(:other_user) { create(:user) }
189
+ let(:params) { { product_id: product.id, id: review.id, token: other_user.spree_api_key, format: 'json' }.merge(review_params) }
190
+
191
+ before do
192
+ other_user.generate_spree_api_key!
193
+ end
194
+
195
+ it 'should return an error' do
196
+ expect(subject["error"]).not_to be_empty
197
+ expect(subject["error"]).to match(/not authorized/i)
198
+ end
199
+ end
200
+ end
201
+
202
+ describe '#destroy' do
203
+ before { review.update(approved: true, user_id: user.id) }
204
+ let(:params) { { product_id: product.id, id: review.id, token: user.spree_api_key, format: 'json' } }
205
+
206
+ subject do
207
+ delete :destroy, params: params
208
+ JSON.parse(response.body)
209
+ end
210
+
211
+ context "when a user destroys their own review" do
212
+ it 'should return the deleted review' do
213
+ expect(subject["id"]).to eq(review.id)
214
+ expect(subject["product_id"]).to eq(product.id)
215
+ expect(Spree::Review.find_by(id: review.id)).to be_falsey
216
+ end
217
+ end
218
+
219
+ context "when a user destroys another users review" do
220
+ let(:other_user) { create(:user) }
221
+ let(:params) { { product_id: product.id, id: review.id, token: other_user.spree_api_key, format: 'json' } }
222
+
223
+ before do
224
+ other_user.generate_spree_api_key!
225
+ end
226
+
227
+ it 'should return an error' do
228
+ expect(subject["error"]).not_to be_empty
229
+ expect(subject["error"]).to match(/not authorized/i)
230
+ end
231
+ end
232
+ end
233
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  RSpec.feature 'Review Admin' do
@@ -30,6 +32,7 @@ RSpec.feature 'Review Admin' do
30
32
 
31
33
  expect(page).to have_text 'Editing'
32
34
  expect(page).to have_text review.title
35
+ expect(page).to have_css('a', text: review.email)
33
36
  end
34
37
  end
35
38
  end