Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add edit and update methods to reviews controller #76

Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 28 additions & 1 deletion app/controllers/spree/reviews_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

class Spree::ReviewsController < Spree::StoreController
helper Spree::BaseHelper
before_action :load_product, only: [:index, :new, :create]
before_action :load_product, only: [:index, :new, :create, :edit, :update]

def index
@approved_reviews = Spree::Review.approved.where(product: @product)
Expand All @@ -13,6 +13,14 @@ def new
authorize! :create, @review
end

def edit
@review = Spree::Review.find(params[:id])
if @review.product.nil?
flash[:error] = I18n.t('spree.error_no_product')
end
authorize! :update, @review
end

# save if all ok
def create
params[:review][:rating].sub!(/\s*[^0-9]*\z/, '') if params[:review][:rating].present?
Expand All @@ -36,6 +44,25 @@ def create
end
end

def update
params[:review][:rating].sub!(/\s*[^0-9]*\z/, '') if params[:review][:rating].present?
KaemonIsland marked this conversation as resolved.
Show resolved Hide resolved

@review = Spree::Review.find(params[:id])

# Handle images
params[:review][:images]&.each do |image|
@review.images.new(attachment: image)
end

authorize! :update, @review
if @review.update(review_params)
flash[:notice] = I18n.t('spree.review_successfully_submitted')
redirect_to spree.product_path(@product)
else
render :edit
end
end

private

def load_product
Expand Down
3 changes: 3 additions & 0 deletions app/views/spree/reviews/edit.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<%= content_tag :h2, I18n.t("spree.leave_us_a_review_for", name: @product.name), class: 'new-review-title' %>

<%= render 'form', review: @review, product: @product %>
2 changes: 1 addition & 1 deletion config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
end

resources :products, only: [] do
resources :reviews, only: [:index, :new, :create] do
resources :reviews, only: [:index, :new, :create, :edit, :update] do
end
end
post '/reviews/:review_id/feedback(.:format)' => 'feedback_reviews#create', as: :feedback_reviews
Expand Down
136 changes: 136 additions & 0 deletions spec/controllers/spree/reviews_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
describe Spree::ReviewsController, type: :controller do
let(:user) { create(:user) }
let(:product) { create(:product) }
let(:review) { create(:review, :approved, product: product, user: user) }
let(:review_params) do
{ product_id: product.slug,
review: { rating: 3,
Expand Down Expand Up @@ -67,6 +68,40 @@
end
end

describe '#edit' do

context 'for a product that does not exist' do
it 'responds with a 404' do
expect {
get :edit, params: { id: review.id, product_id: 'not_real' }
}.to raise_error(ActiveRecord::RecordNotFound)
end
end

it 'fail if the user is not authorized to edit a review' do
allow(controller).to receive(:authorize!).and_raise(RuntimeError)

expect {
post :edit, params: { id: review.id, product_id: product.slug }
assert_match 'ryanbig', response.body
}.to raise_error RuntimeError
end

it 'render the edit template' do
get :edit, params: { id: review.id, product_id: product.slug }
expect(response.status).to eq(200)
expect(response).to render_template(:edit)
end

it 'doesn\'t allow another user to update a users review' do
other_user = create(:user)
allow(controller).to receive(:spree_current_user).and_return(other_user)
get :edit, params: {id: review.id, product_id: product.slug }
expect(response).to_not render_template(:edit)
expect(flash[:error]).to eq "Authorization Failure"
end
end

describe '#create' do
before { allow(controller).to receive(:spree_current_user).and_return(user) }

Expand Down Expand Up @@ -159,4 +194,105 @@
end
end
end

describe '#update' do
before {
allow(controller).to receive(:spree_current_user).and_return(user)
@review_params = { product_id: product.slug,
id: review.id,
review: { title: 'Amazing Product' } }
}

context 'for a product that does not exist' do
it 'responds with a 404' do
expect {
post :update, params: { id: review.id, product_id: 'not_real' }
}.to raise_error(ActiveRecord::RecordNotFound)
end
end

it 'updates a review' do
post :update, params: @review_params

expect(assigns[:review].title).to eq 'Amazing Product'
expect(assigns[:review].product).to eq product
expect(assigns[:review].user).to eq user
end

it 'updates a review to be a rating only review' do
post :update, params: {
product_id: product.slug,
id: review.id,
review: { title: '', review: '', rating: 5 }
}

expect(assigns[:review].title).to eq ''
expect(assigns[:review].review).to eq ''
expect(assigns[:review].rating).to eq 5
end

it 'updates the attached image' do
post :update, params: {
product_id: product.slug,
id: review.id,
review: {
images: [
fixture_file_upload(File.new(Spree::Core::Engine.root + 'spec/fixtures/thinking-cat.jpg')),
] }
}
expect(assigns[:review].images.count).to eq 1
end

it 'fails if the user is not authorized to create a review' do
allow(controller).to receive(:authorize!).and_raise(RuntimeError)

expect{
post :update, params: @review_params
}.to raise_error RuntimeError
end

it 'flashes the notice' do
post :update, params: @review_params

expect(flash[:notice]).to eq I18n.t('spree.review_successfully_submitted')
end

it 'redirects to product page' do
post :update, params: @review_params
review.reload
review.valid?
expect(response).to redirect_to spree.product_path(product)
end

it 'removes all non-numbers from ratings param' do
@review_params[:review][:rating] = 5
post :update, params: @review_params
expect(controller.params[:review][:rating]).to eq '5'
end

it 'doesnt change the current spree user as reviews user' do
post :update, params: @review_params
expect(assigns[:review].user_id).to eq user.id
end

context 'with invalid params' do
it 'renders edit when review.save fails' do
expect_any_instance_of(Spree::Review).to receive(:update).and_return(false)
post :update, params: @review_params
expect(response).to render_template :edit
end

it 'does not update a review' do
original_rating = review.rating
original_title = review.title
@review_params[:review][:rating] = 'not_a_number'
@review_params[:review][:title] = true
post :update, params: @review_params

review.reload
expect(review.rating).to eq original_rating
expect(review.title).to eq original_title
end
end
end
end