summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/controllers/api/reviews_controller.rb8
-rw-r--r--app/models/product_review.rb2
-rw-r--r--app/queries/reviews/has_user_already_posted_review_query.rb14
-rw-r--r--spec/factories/product.rb1
-rw-r--r--spec/factories/product_review.rb2
-rw-r--r--spec/requests/reviews_controller/create_spec.rb26
-rw-r--r--spec/requests/reviews_controller/index_spec.rb25
7 files changed, 76 insertions, 2 deletions
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