From 3980d2e9f8d7fdfbd302be71444de8faabd3dd0b Mon Sep 17 00:00:00 2001 From: Erik Csonka Date: Tue, 29 Oct 2019 12:37:08 +0100 Subject: [PATCH 01/10] Allow all spree version between 3.1.0 and 5.0 --- spree_reviews.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spree_reviews.gemspec b/spree_reviews.gemspec index 9dd61085..19d36756 100644 --- a/spree_reviews.gemspec +++ b/spree_reviews.gemspec @@ -21,7 +21,7 @@ Gem::Specification.new do |s| s.require_path = 'lib' s.requirements << 'none' - spree_version = '>= 3.1.0', '< 4.0' + spree_version = '>= 3.1.0', '< 5.0' s.add_runtime_dependency 'spree_core', spree_version s.add_runtime_dependency 'spree_auth_devise', spree_version s.add_runtime_dependency 'spree_extension' From f81458755d8949cc7d2ec7d44632d3e3ccd58f78 Mon Sep 17 00:00:00 2001 From: Janos Seller Date: Mon, 11 Nov 2019 17:12:23 +0100 Subject: [PATCH 02/10] Remove class_evals and add prepend to decorators based on spree 4 update --- app/controllers/spree/products_controller_decorator.rb | 8 ++++++-- app/models/spree/product_decorator.rb | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/app/controllers/spree/products_controller_decorator.rb b/app/controllers/spree/products_controller_decorator.rb index a231a1ce..bf206e37 100644 --- a/app/controllers/spree/products_controller_decorator.rb +++ b/app/controllers/spree/products_controller_decorator.rb @@ -1,5 +1,7 @@ -Spree::ProductsController.class_eval do - helper Spree::ReviewsHelper +module Spree::ProductsControllerDecorator + def self.prepended(base) + base.helper Spree::ReviewsHelper + end reviews_fields = [:avg_rating, :reviews_count] reviews_fields.each { |attrib| Spree::PermittedAttributes.product_attributes << attrib } @@ -8,3 +10,5 @@ reviews_fields.each { |attrib| class_variable_set(:@@product_attributes, class_variable_get(:@@product_attributes).push(attrib)) } end end + +::Spree::ProductsController.prepend(Spree::ProductsControllerDecorator) diff --git a/app/models/spree/product_decorator.rb b/app/models/spree/product_decorator.rb index c7a7083f..92f4a860 100644 --- a/app/models/spree/product_decorator.rb +++ b/app/models/spree/product_decorator.rb @@ -1,6 +1,8 @@ # Add access to reviews/ratings to the product model -Spree::Product.class_eval do - has_many :reviews +module Spree::ProductDecorator + def self.prepended(base) + base.has_many :reviews + end def stars avg_rating.try(:round) || 0 @@ -16,3 +18,5 @@ def recalculate_rating save end end + +::Spree::Product.prepend(Spree::ProductDecorator) From 6669caac4c9f4dd92ff01f1c58318161810343d0 Mon Sep 17 00:00:00 2001 From: Prakash Poudel Date: Fri, 18 Sep 2020 18:13:54 +0545 Subject: [PATCH 03/10] Spree 4 compatibility --- .travis.yml | 3 ++ Appraisals | 6 ++++ README.md | 2 +- .../spree/frontend/spree_reviews.js | 1 - app/models/spree/product_decorator.rb | 31 ++++++++++++------- gemfiles/spree_4_0.gemfile | 9 ++++++ spree_reviews.gemspec | 2 +- 7 files changed, 39 insertions(+), 15 deletions(-) create mode 100644 gemfiles/spree_4_0.gemfile diff --git a/.travis.yml b/.travis.yml index 5c2f8313..a4497470 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,6 +10,7 @@ env: gemfile: - gemfiles/spree_3_1.gemfile - gemfiles/spree_3_2.gemfile + - gemfiles/spree_4_0.gemfile - gemfiles/spree_master.gemfile script: @@ -19,8 +20,10 @@ script: rvm: - 2.3.1 - 2.2.7 + - 2.3.8 addons: + postgresql: 9.4 apt: packages: - mysql-server-5.6 diff --git a/Appraisals b/Appraisals index cfe64a61..cdba851e 100644 --- a/Appraisals +++ b/Appraisals @@ -15,6 +15,12 @@ appraise 'spree-3-3' do gem 'rails-controller-testing' end +appraise 'spree-4-0' do + gem 'spree', '~> 4.0.0' + gem 'spree_auth_devise', '~> 4.0' + gem 'rails-controller-testing' +end + appraise 'spree-master' do gem 'spree', github: 'spree/spree', branch: 'master' gem 'spree_auth_devise', github: 'spree/spree_auth_devise', branch: 'master' diff --git a/README.md b/README.md index 9ab34bf4..cfe4c544 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Straightforward review/rating functionality. ## Installation -#### Spree >= 3.1 +#### Spree >= 4.0 ```ruby gem 'spree_reviews', github: 'spree-contrib/spree_reviews' diff --git a/app/assets/javascripts/spree/frontend/spree_reviews.js b/app/assets/javascripts/spree/frontend/spree_reviews.js index f70c6184..9346fd21 100644 --- a/app/assets/javascripts/spree/frontend/spree_reviews.js +++ b/app/assets/javascripts/spree/frontend/spree_reviews.js @@ -1,6 +1,5 @@ //= require jquery.rating //= require spree/frontend -//= require spree/frontend/spree_auth // Navigating to a page with ratings via TurboLinks shows the radio buttons $(document).on('page:load', function () { diff --git a/app/models/spree/product_decorator.rb b/app/models/spree/product_decorator.rb index c7a7083f..86ecb786 100644 --- a/app/models/spree/product_decorator.rb +++ b/app/models/spree/product_decorator.rb @@ -1,18 +1,25 @@ # Add access to reviews/ratings to the product model -Spree::Product.class_eval do - has_many :reviews +module Spree + module ProductDecorator - def stars - avg_rating.try(:round) || 0 - end + def self.prepended(base) + base.has_many :reviews + end - def recalculate_rating - self[:reviews_count] = reviews.reload.approved.count - if reviews_count > 0 - self[:avg_rating] = reviews.approved.sum(:rating).to_f / reviews_count - else - self[:avg_rating] = 0 + def stars + avg_rating.try(:round) || 0 + end + + def recalculate_rating + self[:reviews_count] = reviews.reload.approved.count + if reviews_count > 0 + self[:avg_rating] = reviews.approved.sum(:rating).to_f / reviews_count + else + self[:avg_rating] = 0 + end + save end - save end end + +Spree::Product.prepend Spree::ProductDecorator diff --git a/gemfiles/spree_4_0.gemfile b/gemfiles/spree_4_0.gemfile new file mode 100644 index 00000000..82154e3a --- /dev/null +++ b/gemfiles/spree_4_0.gemfile @@ -0,0 +1,9 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "spree", "~> 4.0.0" +gem "spree_auth_devise", "~> 4.0" +gem "rails-controller-testing" + +gemspec path: "../" diff --git a/spree_reviews.gemspec b/spree_reviews.gemspec index 9dd61085..19d36756 100644 --- a/spree_reviews.gemspec +++ b/spree_reviews.gemspec @@ -21,7 +21,7 @@ Gem::Specification.new do |s| s.require_path = 'lib' s.requirements << 'none' - spree_version = '>= 3.1.0', '< 4.0' + spree_version = '>= 3.1.0', '< 5.0' s.add_runtime_dependency 'spree_core', spree_version s.add_runtime_dependency 'spree_auth_devise', spree_version s.add_runtime_dependency 'spree_extension' From 6f547948e1a71bea70a7530eadfd02ca352c13d6 Mon Sep 17 00:00:00 2001 From: Prakash Poudel Date: Fri, 18 Sep 2020 19:10:15 +0545 Subject: [PATCH 04/10] Add Review Show Api --- .../storefront/product_reviews_controller.rb | 29 +++++++++++++++++++ .../spree/v2/storefront/review_serializer.rb | 14 +++++++++ config/routes.rb | 8 +++++ 3 files changed, 51 insertions(+) create mode 100644 app/controllers/spree/api/v2/storefront/product_reviews_controller.rb create mode 100644 app/serializers/spree/v2/storefront/review_serializer.rb diff --git a/app/controllers/spree/api/v2/storefront/product_reviews_controller.rb b/app/controllers/spree/api/v2/storefront/product_reviews_controller.rb new file mode 100644 index 00000000..4efd60c2 --- /dev/null +++ b/app/controllers/spree/api/v2/storefront/product_reviews_controller.rb @@ -0,0 +1,29 @@ +module Spree + module Api + module V2 + module Storefront + class ProductReviewsController < ::Spree::Api::V2::BaseController + + def show + render_serialized_payload { serialize_resource(resource) } + end + + private + + def scope + Spree::Review + end + + def resource + scope.find(params[:id]) + end + + def resource_serializer + Spree::V2::Storefront::ReviewSerializer + end + + end + end + end + end +end diff --git a/app/serializers/spree/v2/storefront/review_serializer.rb b/app/serializers/spree/v2/storefront/review_serializer.rb new file mode 100644 index 00000000..f9bf1678 --- /dev/null +++ b/app/serializers/spree/v2/storefront/review_serializer.rb @@ -0,0 +1,14 @@ +module Spree + module V2 + module Storefront + class ReviewSerializer < BaseSerializer + set_type :review + + attributes :title, :review, :approved + + has_one :user + has_one :product + end + end + end +end diff --git a/config/routes.rb b/config/routes.rb index ce787ddc..e9033bae 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -14,4 +14,12 @@ end end post '/reviews/:review_id/feedback(.:format)' => 'feedback_reviews#create', as: :feedback_reviews + + namespace :api, defaults: { format: 'json' } do + namespace :v2 do + namespace :storefront do + resources :product_reviews + end + end + end end From bb88fe96355574615fc54e57d88447e47585ea58 Mon Sep 17 00:00:00 2001 From: Prakash Poudel Date: Sun, 20 Sep 2020 20:04:51 +0545 Subject: [PATCH 05/10] Product Review index and create API --- .../api/v2/storefront/reviews_controller.rb | 97 +++++++++++++++++++ app/models/spree/review.rb | 2 +- .../spree/v2/storefront/review_serializer.rb | 2 +- config/routes.rb | 4 +- 4 files changed, 102 insertions(+), 3 deletions(-) create mode 100644 app/controllers/spree/api/v2/storefront/reviews_controller.rb diff --git a/app/controllers/spree/api/v2/storefront/reviews_controller.rb b/app/controllers/spree/api/v2/storefront/reviews_controller.rb new file mode 100644 index 00000000..3720a923 --- /dev/null +++ b/app/controllers/spree/api/v2/storefront/reviews_controller.rb @@ -0,0 +1,97 @@ +module Spree + module Api + module V2 + module Storefront + class ReviewsController < ::Spree::Api::V2::BaseController + include Spree::Api::V2::CollectionOptionsHelpers + + before_action :load_product, only: [:index, :create] + + def index + render_serialized_payload {serialize_collection(paginated_collection)} + end + + def show + render_serialized_payload {serialize_resource(resource)} + end + + def create + # TODO move to service + # result = create_service.call(user: spree_current_user, review_params: review_params, product: @product, ip_address: request.remote_ip) + + params[:review][:rating].sub!(/\s*[^0-9]*\z/, '') unless params[:review][:rating].blank? + + @review = Spree::Review.new(review_params) + @review.product = @product + @review.user = spree_current_user if spree_user_signed_in? + @review.ip_address = request.remote_ip + @review.locale = I18n.locale.to_s if Spree::Reviews::Config[:track_locale] + + # TODO: @prakash fix permission + # authorize! :create, @review + + render_result(@review) + end + + private + + def create_service + Spree::Api::Dependencies.storefront_account_create_address_service.constantize + end + + def scope + Spree::Review + end + + def resource + scope.find(params[:id]) + end + + def collection_serializer + Spree::V2::Storefront::ReviewSerializer + end + + def resource_serializer + Spree::V2::Storefront::ReviewSerializer + end + + def paginated_collection + collection_paginator.new(collection, params).call + end + + def collection + Spree::Review.approved.where(product: @product) + end + + def load_product + @product = Spree::Product.friendly.find(params[:product_id]) + end + + def permitted_review_attributes + [:rating, :title, :review, :name, :show_identifier] + end + + def review_params + params.require(:review).permit(permitted_review_attributes) + end + + def render_result(review) + if review.save + render_serialized_payload {serialize_resource(review)} + else + # TODO handle error from service + render_error_payload(review.errors) + end + # if result.success? + # render_serialized_payload { serialize_resource(result.value) } + # else + # render_error_payload(result.error) + # end + end + + + end + end + end + end +end diff --git a/app/models/spree/review.rb b/app/models/spree/review.rb index a8724821..f200b7d2 100644 --- a/app/models/spree/review.rb +++ b/app/models/spree/review.rb @@ -1,6 +1,6 @@ class Spree::Review < ActiveRecord::Base belongs_to :product, touch: true - belongs_to :user, class_name: Spree.user_class.to_s + belongs_to :user, class_name: Spree.user_class.to_s, optional: true has_many :feedback_reviews after_save :recalculate_product_rating, if: :approved? diff --git a/app/serializers/spree/v2/storefront/review_serializer.rb b/app/serializers/spree/v2/storefront/review_serializer.rb index f9bf1678..88dfedb4 100644 --- a/app/serializers/spree/v2/storefront/review_serializer.rb +++ b/app/serializers/spree/v2/storefront/review_serializer.rb @@ -4,7 +4,7 @@ module Storefront class ReviewSerializer < BaseSerializer set_type :review - attributes :title, :review, :approved + attributes :title, :review has_one :user has_one :product diff --git a/config/routes.rb b/config/routes.rb index e9033bae..41e9ebb1 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -18,7 +18,9 @@ namespace :api, defaults: { format: 'json' } do namespace :v2 do namespace :storefront do - resources :product_reviews + resources :products, only: [] do + resources :reviews, only: [:index, :create] + end end end end From 7986ca072102a23a45e7f8241b9f57648a1b4b96 Mon Sep 17 00:00:00 2001 From: Prakash Date: Fri, 25 Sep 2020 02:53:35 +0545 Subject: [PATCH 06/10] Delete product_reviews_controller.rb --- .../storefront/product_reviews_controller.rb | 29 ------------------- 1 file changed, 29 deletions(-) delete mode 100644 app/controllers/spree/api/v2/storefront/product_reviews_controller.rb diff --git a/app/controllers/spree/api/v2/storefront/product_reviews_controller.rb b/app/controllers/spree/api/v2/storefront/product_reviews_controller.rb deleted file mode 100644 index 4efd60c2..00000000 --- a/app/controllers/spree/api/v2/storefront/product_reviews_controller.rb +++ /dev/null @@ -1,29 +0,0 @@ -module Spree - module Api - module V2 - module Storefront - class ProductReviewsController < ::Spree::Api::V2::BaseController - - def show - render_serialized_payload { serialize_resource(resource) } - end - - private - - def scope - Spree::Review - end - - def resource - scope.find(params[:id]) - end - - def resource_serializer - Spree::V2::Storefront::ReviewSerializer - end - - end - end - end - end -end From 560723b8b983b5902b41daa5194e9cd273330faf Mon Sep 17 00:00:00 2001 From: khadka_bibek Date: Sat, 21 Nov 2020 23:32:56 +1100 Subject: [PATCH 07/10] Display all user reviews --- .../account/user_reviews_controller.rb | 40 +++++++++++++++++++ app/models/spree/review.rb | 1 + config/routes.rb | 4 ++ 3 files changed, 45 insertions(+) create mode 100644 app/controllers/spree/api/v2/storefront/account/user_reviews_controller.rb diff --git a/app/controllers/spree/api/v2/storefront/account/user_reviews_controller.rb b/app/controllers/spree/api/v2/storefront/account/user_reviews_controller.rb new file mode 100644 index 00000000..40405f47 --- /dev/null +++ b/app/controllers/spree/api/v2/storefront/account/user_reviews_controller.rb @@ -0,0 +1,40 @@ +module Spree + module Api + module V2 + module Storefront + module Account + class UserReviewsController < ::Spree::Api::V2::BaseController + before_action :require_spree_current_user + + # GET /api/v2/storefront/account/reviews + def index + render_serialized_payload { serialize_collection(resource) } + end + + private + + def resource + resource_finder.user_reviews(1).most_recent_first + end + + def collection_serializer + Spree::V2::Storefront::ReviewSerializer + end + + def serialize_collection(collection) + collection_serializer.new( + collection, + include: resource_includes, + fields: sparse_fields + ).serializable_hash + end + + def resource_finder + Spree::Review + end + end + end + end + end + end +end diff --git a/app/models/spree/review.rb b/app/models/spree/review.rb index f200b7d2..c5108378 100644 --- a/app/models/spree/review.rb +++ b/app/models/spree/review.rb @@ -23,6 +23,7 @@ class Spree::Review < ActiveRecord::Base scope :approved, -> { where(approved: true) } scope :not_approved, -> { where(approved: false) } scope :default_approval_filter, -> { Spree::Reviews::Config[:include_unapproved_reviews] ? all : approved } + scope :user_reviews, ->(user_id) { where('spree_reviews.user_id = ?', user_id) } def feedback_stars return 0 if feedback_reviews.size <= 0 diff --git a/config/routes.rb b/config/routes.rb index 41e9ebb1..d5c63276 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -21,6 +21,10 @@ resources :products, only: [] do resources :reviews, only: [:index, :create] end + + namespace :account do + resources :reviews, controller: :user_reviews, only: %i[index] + end end end end From d63aecf7181163fca4c81f14f963d47de6d48a4c Mon Sep 17 00:00:00 2001 From: khadka_bibek Date: Sat, 21 Nov 2020 23:33:18 +1100 Subject: [PATCH 08/10] Add spec --- spec/models/review_spec.rb | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/spec/models/review_spec.rb b/spec/models/review_spec.rb index 14d216d7..c8c9146a 100644 --- a/spec/models/review_spec.rb +++ b/spec/models/review_spec.rb @@ -141,6 +141,21 @@ expect(Spree::Review.default_approval_filter.to_a).to match_array expected end end + + context 'user_reviews' do + let!(:user_1) { create(:user, email: 'a@b.com') } + let!(:user_2) { create(:user, email: 'b@c.com') } + let!(:review_1) { create(:review, created_at: 10.days.ago, user: user_1) } + let!(:review_2) { create(:review, created_at: 2.days.ago, user: user_2) } + + it 'properly runs user_reviews queries' do + expect(described_class.user_reviews(user_1).to_a).to eq([review_1]) + end + + it 'does not show other users reviews' do + expect(described_class.user_reviews(user_2).to_a).to eq([review_2]) + end + end end context '.recalculate_product_rating' do From c04db487eb3eba46b37c6eff934f5d44d4528043 Mon Sep 17 00:00:00 2001 From: roringbbk Date: Sat, 21 Nov 2020 23:40:59 +1100 Subject: [PATCH 09/10] Revert test data for unauthenticated user --- .../spree/api/v2/storefront/account/user_reviews_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/spree/api/v2/storefront/account/user_reviews_controller.rb b/app/controllers/spree/api/v2/storefront/account/user_reviews_controller.rb index 40405f47..53d3b73d 100644 --- a/app/controllers/spree/api/v2/storefront/account/user_reviews_controller.rb +++ b/app/controllers/spree/api/v2/storefront/account/user_reviews_controller.rb @@ -14,7 +14,7 @@ def index private def resource - resource_finder.user_reviews(1).most_recent_first + resource_finder.user_reviews(spree_current_user.id).most_recent_first end def collection_serializer From 6102acd7a7eb55240ed55e397db5272fdd47ad50 Mon Sep 17 00:00:00 2001 From: roringbbk Date: Sun, 22 Nov 2020 11:34:49 +1100 Subject: [PATCH 10/10] Add rating to review serializer --- app/serializers/spree/v2/storefront/review_serializer.rb | 2 +- spec/models/review_spec.rb | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/serializers/spree/v2/storefront/review_serializer.rb b/app/serializers/spree/v2/storefront/review_serializer.rb index 88dfedb4..49f0f332 100644 --- a/app/serializers/spree/v2/storefront/review_serializer.rb +++ b/app/serializers/spree/v2/storefront/review_serializer.rb @@ -4,7 +4,7 @@ module Storefront class ReviewSerializer < BaseSerializer set_type :review - attributes :title, :review + attributes :title, :review, :rating has_one :user has_one :product diff --git a/spec/models/review_spec.rb b/spec/models/review_spec.rb index c8c9146a..4595a4f5 100644 --- a/spec/models/review_spec.rb +++ b/spec/models/review_spec.rb @@ -145,6 +145,7 @@ context 'user_reviews' do let!(:user_1) { create(:user, email: 'a@b.com') } let!(:user_2) { create(:user, email: 'b@c.com') } + let!(:review_1) { create(:review, created_at: 10.days.ago, user: user_1) } let!(:review_2) { create(:review, created_at: 2.days.ago, user: user_2) }