Files
openfoodnetwork/spec/controllers/spree/api/variants_controller_spec.rb
Maikel Linke cdb49f88b0 Move Variant deletion into its own service
This keeps the override of Spree's model leaner. More importantly, it
prepares us for using `destroy` instead of `delete`.

In the past, `Product#delete` soft-deleted the product, but didn't
delete the variants. When we use `Product#destroy` to soft-delete the
product, it will also call destroy on the variants. If the model doesn't
allow the deletion of the last variant, it will fail. So when a product
is deleted we want to allow the deletion of all variants. But the user
should not be allowed to delete the last variant. That's why I'm moving
the check to the controller level.

Related commits:

- e6c7acdff3
- 2b47c9145a
- b9f19d5777 (diff-412c5af2ec1ba9f6643f6df5a673c1d4R105)
2019-02-19 14:25:18 +11:00

85 lines
3.1 KiB
Ruby

require 'spec_helper'
module Spree
describe Spree::Api::VariantsController, type: :controller do
render_views
let(:supplier) { FactoryBot.create(:supplier_enterprise) }
let!(:variant1) { FactoryBot.create(:variant) }
let!(:variant2) { FactoryBot.create(:variant) }
let!(:variant3) { FactoryBot.create(:variant) }
let(:attributes) { [:id, :options_text, :price, :on_hand, :unit_value, :unit_description, :on_demand, :display_as, :display_name] }
before do
allow(controller).to receive(:spree_current_user) { current_api_user }
end
context "as a normal user" do
sign_in_as_user!
it "retrieves a list of variants with appropriate attributes" do
spree_get :index, { :template => 'bulk_index', :format => :json }
keys = json_response.first.keys.map{ |key| key.to_sym }
attributes.all?{ |attr| keys.include? attr }.should == true
end
it "is denied access when trying to delete a variant" do
product = create(:product)
variant = product.master
spree_delete :soft_delete, {variant_id: variant.to_param, product_id: product.to_param, format: :json}
assert_unauthorized!
lambda { variant.reload }.should_not raise_error
variant.deleted_at.should be_nil
end
end
context "as an enterprise user" do
sign_in_as_enterprise_user! [:supplier]
let(:supplier_other) { create(:supplier_enterprise) }
let(:product) { create(:product, supplier: supplier) }
let(:variant) { product.master }
let(:product_other) { create(:product, supplier: supplier_other) }
let(:variant_other) { product_other.master }
it "soft deletes a variant" do
spree_delete :soft_delete, {variant_id: variant.to_param, product_id: product.to_param, format: :json}
response.status.should == 204
lambda { variant.reload }.should_not raise_error
variant.deleted_at.should be_present
end
it "is denied access to soft deleting another enterprises' variant" do
spree_delete :soft_delete, {variant_id: variant_other.to_param, product_id: product_other.to_param, format: :json}
assert_unauthorized!
lambda { variant.reload }.should_not raise_error
variant.deleted_at.should be_nil
end
end
context "as an administrator" do
sign_in_as_admin!
it "soft deletes a variant" do
product = create(:product)
variant = product.master
spree_delete :soft_delete, {variant_id: variant.to_param, product_id: product.to_param, format: :json}
response.status.should == 204
lambda { variant.reload }.should_not raise_error
variant.deleted_at.should_not be_nil
end
it "doesn't delete the only variant of the product" do
product = create(:product)
variant = product.variants.first
spree_delete :soft_delete, {variant_id: variant.to_param, product_id: product.to_param, format: :json}
expect(variant.reload).to_not be_deleted
expect(assigns(:variant).errors[:product]).to include "must have at least one variant"
end
end
end
end