mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-24 20:36:49 +00:00
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)
85 lines
3.1 KiB
Ruby
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
|