solidus_reviews 1.0.0 → 1.4.0

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