From 72ccdfdf9bbea6269bc1a28199373abd5e8ce302 Mon Sep 17 00:00:00 2001 From: HombreLaser Date: Tue, 4 Apr 2023 19:53:27 -0600 Subject: AƱade specs de ReviewsController MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/api/reviews_controller.rb | 8 ++++++- app/models/product_review.rb | 2 ++ .../has_user_already_posted_review_query.rb | 14 ++++++++++++ spec/factories/product.rb | 1 + spec/factories/product_review.rb | 2 +- spec/requests/reviews_controller/create_spec.rb | 26 ++++++++++++++++++++++ spec/requests/reviews_controller/index_spec.rb | 25 +++++++++++++++++++++ 7 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 app/queries/reviews/has_user_already_posted_review_query.rb create mode 100644 spec/requests/reviews_controller/create_spec.rb create mode 100644 spec/requests/reviews_controller/index_spec.rb diff --git a/app/controllers/api/reviews_controller.rb b/app/controllers/api/reviews_controller.rb index 1f48362..52e7ec3 100644 --- a/app/controllers/api/reviews_controller.rb +++ b/app/controllers/api/reviews_controller.rb @@ -10,6 +10,12 @@ module Api render status: :not_found and return if @product.nil? + if params[:by].present? + render json: { posted: Reviews::HasUserAlreadyPostedReviewQuery.new(@product).review_posted?(params[:by]) }, + status: :ok + return + end + @reviews = @product.product_reviews.joins(:user_account).select('product_reviews.*', 'user_accounts.first_name as author_name') render json: serialized_collection.serializable_hash, status: :ok @@ -41,7 +47,7 @@ module Api end def serialized_collection - @serialized_collection ||= ProductReviewSerializer.new(@reviews) + @serialized_collection ||= ProductReviewSerializer.new(@reviews.page(params[:page])) end def serialized_object diff --git a/app/models/product_review.rb b/app/models/product_review.rb index 0985e7c..85804f2 100644 --- a/app/models/product_review.rb +++ b/app/models/product_review.rb @@ -11,6 +11,8 @@ class ProductReview < ApplicationRecord validates :rating, presence: true, inclusion: { in: 1..5 } validate :sole_user_review + paginates_per 15 + def sole_user_review return if ProductReview.find_by(user_account_id:, product_id:).nil? diff --git a/app/queries/reviews/has_user_already_posted_review_query.rb b/app/queries/reviews/has_user_already_posted_review_query.rb new file mode 100644 index 0000000..182f12e --- /dev/null +++ b/app/queries/reviews/has_user_already_posted_review_query.rb @@ -0,0 +1,14 @@ +# frozen_string_literal + +module Reviews + # HasUserAlreadyPostedReviewQuery + class HasUserAlreadyPostedReviewQuery + def initialize(product) + @product = product + end + + def review_posted?(user_account_id) + ProductReview.find_by(user_account_id:, product_id: @product.id).present? + end + end +end diff --git a/spec/factories/product.rb b/spec/factories/product.rb index fb64d0d..8f643a6 100644 --- a/spec/factories/product.rb +++ b/spec/factories/product.rb @@ -14,5 +14,6 @@ FactoryBot.define do end c end + public_id { SecureRandom.hex(12) } end end diff --git a/spec/factories/product_review.rb b/spec/factories/product_review.rb index b9778bd..543eda3 100644 --- a/spec/factories/product_review.rb +++ b/spec/factories/product_review.rb @@ -4,7 +4,7 @@ FactoryBot.define do factory :product_review, class: 'ProductReview' do user_account { create(:user_account) } product { create(:product) } - review { Faker::Lorem.paragraphs } + review { Faker::Lorem.paragraph } rating { rand(1..5) } end end diff --git a/spec/requests/reviews_controller/create_spec.rb b/spec/requests/reviews_controller/create_spec.rb new file mode 100644 index 0000000..8ff2f0c --- /dev/null +++ b/spec/requests/reviews_controller/create_spec.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'POST /api/products/:product_id/reviews', type: :request do + let(:review) { build(:product_review) } + let(:product) { create(:product) } + let(:user) { create(:user_account, role: 'regular') } + let(:headers) { { 'Authorization' => "Bearer #{token['token']}" } } + let(:token) { jwt(user) } + let(:params) { { review: review.review, rating: review.rating } } + + it_behaves_like 'a POST request' do + let(:route) { "/api/products/#{product.public_id}/reviews" } + let(:expected_error_messages) do + ["can't be blank", "can't be blank", 'is not included in the list'] + end + let(:desired_error_status) { 422 } + let(:expected_text) do + [review.review, review.rating] + end + let(:wrong_params) do + { review: '', rating: '' } + end + end +end diff --git a/spec/requests/reviews_controller/index_spec.rb b/spec/requests/reviews_controller/index_spec.rb new file mode 100644 index 0000000..1a2863d --- /dev/null +++ b/spec/requests/reviews_controller/index_spec.rb @@ -0,0 +1,25 @@ +require 'rails_helper' + +RSpec.describe 'GET /api/products/:product_id/reviews', type: :request do + let!(:product) { create(:product, public_id: SecureRandom.hex(12)) } + + before(:each) do + create_list(:product_review, 26, product:) + end + + it_behaves_like 'a GET index request' do + let(:headers) { {} } + let(:route) { "/api/products/#{product.public_id}/reviews" } + let(:pagination_size) { 15 } + end + + describe '?by=:user_account_id' do + it 'tells if a product has a review made by the user with the id' do + user = create(:user_account) + create(:product_review, user_account: user, product:) + get "/api/products/#{product.public_id}/reviews?by=#{user.id}" + expect(response).to have_http_status(200) + expect(response.body).to include('true') + end + end +end -- cgit v1.2.3