# frozen_string_literal: true require 'spec_helper' RSpec.describe Enterprise do describe "sending emails" do describe "on creation" do let!(:user) { create(:user) } let!(:enterprise) { create(:enterprise, owner: user) } it "sends a welcome email" do expect do create(:enterprise, owner: user) end.to enqueue_job ActionMailer::MailDeliveryJob expect(enqueued_jobs.last.to_s).to match "welcome" end end end describe "associations" do it { is_expected.to belong_to(:owner).required } it { is_expected.to have_many(:supplied_products) } it { is_expected.to have_many(:supplied_variants) } it { is_expected.to have_many(:distributed_orders) } it { is_expected.to belong_to(:address).required } it { is_expected.to belong_to(:business_address).optional } it { is_expected.to have_many(:vouchers) } it "destroys enterprise roles upon its own demise" do e = create(:enterprise) u = create(:user) u.enterprise_roles.build(enterprise: e).save! role = e.enterprise_roles.first e.destroy expect(EnterpriseRole.where(id: role.id)).to be_empty end it "destroys supplied variants upon destroy" do pending "Variant are soft deletable, see: https://github.com/openfoodfoundation/openfoodnetwork/issues/2971" supplier = create(:supplier_enterprise) variant = create(:variant, supplier:) supplier.destroy expect(Spree::Variant.where(id: variant.id)).to be_empty end it "destroys relationships upon destroy" do e = create(:enterprise) e_other = create(:enterprise) er1 = create(:enterprise_relationship, parent: e, child: e_other) er2 = create(:enterprise_relationship, child: e, parent: e_other) e.destroy expect(EnterpriseRelationship.where(id: [er1, er2])).to be_empty end it "does not destroy distributed_orders upon destroy" do enterprise = create(:distributor_enterprise) create_list(:order, 2, distributor: enterprise) expect do enterprise.destroy expect(enterprise.errors.full_messages).to eq( ["Cannot delete record because dependent distributed orders exist"] ) end.to change { Spree::Order.count }.by(0) end it "does not destroy distributor_payment_methods upon destroy" do enterprise = create(:distributor_enterprise) create_list(:distributor_payment_method, 2, distributor: enterprise) expect do enterprise.destroy expect(enterprise.errors.full_messages).to eq( ["Cannot delete record because dependent distributor payment methods exist"] ) end.to change { Spree::Order.count }.by(0) end it "does not destroy distributor_shipping_methods upon destroy" do enterprise = create(:distributor_enterprise) create_list(:distributor_shipping_method, 2, distributor: enterprise) expect do enterprise.destroy expect(enterprise.errors.full_messages).to eq( ["Cannot delete record because dependent distributor shipping methods exist"] ) end.to change { Spree::Order.count }.by(0) end it "does not destroy enterprise_fees upon destroy" do enterprise = create(:enterprise) create_list(:enterprise_fee, 2, enterprise:) expect do enterprise.destroy expect(enterprise.errors.full_messages).to eq( ["Cannot delete record because dependent enterprise fees exist"] ) end.to change { Spree::Order.count }.by(0) end it "does not destroy vouchers upon destroy" do enterprise = create(:enterprise) (1..2).map do |code| create(:voucher, enterprise:, code: "new code #{code}") end expect do enterprise.destroy expect(enterprise.errors.full_messages).to eq( ["Cannot delete record because dependent vouchers exist"] ) end.to change { Spree::Order.count }.by(0) end describe "relationships to other enterprises" do let(:e) { create(:distributor_enterprise) } let(:p) { create(:supplier_enterprise) } let(:c) { create(:distributor_enterprise) } let!(:er1) { create(:enterprise_relationship, parent_id: p.id, child_id: e.id) } let!(:er2) { create(:enterprise_relationship, parent_id: e.id, child_id: c.id) } it "finds relatives" do expect(e.relatives).to match_array [p, c] end it "finds relatives_including_self" do expect(e.relatives_including_self).to include e end it "scopes relatives to visible distributors" do enterprise = build_stubbed(:distributor_enterprise) expect(enterprise).to receive(:relatives_including_self).and_return(relatives = []) expect(relatives).to receive(:is_distributor).and_return relatives enterprise.distributors end it "scopes relatives to visible producers" do enterprise = build_stubbed(:distributor_enterprise) expect(enterprise).to receive(:relatives_including_self).and_return(relatives = []) expect(relatives).to receive(:is_primary_producer).and_return relatives enterprise.suppliers end end describe "ownership" do let(:u1) { create(:user) } let(:u2) { create(:user) } let!(:e) { create(:enterprise, owner: u1 ) } it "adds new owner to list of managers" do expect(e.owner).to eq u1 expect(e.users).to include u1 expect(e.users).not_to include u2 e.owner = u2 e.save! e.reload expect(e.owner).to eq u2 expect(e.users).to include u1, u2 end it "validates ownership limit" do expect(u1.enterprise_limit).to be 5 expect(u1.owned_enterprises.reload).to eq [e] 4.times { create(:enterprise, owner: u1) } e2 = create(:enterprise, owner: u2) expect { e2.owner = u1 e2.save! }.to raise_error ActiveRecord::RecordInvalid, "Validation failed: #{u1.email} is not permitted " \ "to own any more enterprises (limit is 5)." end end end describe "validations" do it { is_expected.to validate_presence_of(:name) } it do create(:distributor_enterprise) is_expected.to validate_uniqueness_of(:permalink) end describe "name uniqueness" do let(:owner) { create(:user, email: 'owner@example.com') } let!(:enterprise) { create(:enterprise, name: 'Enterprise', owner:) } it "prevents duplicate names for new records" do e = Enterprise.new name: enterprise.name expect(e).not_to be_valid expect(e.errors[:name].first).to include enterprise_name_error(owner.email) end it "prevents duplicate names for existing records" do e = create(:enterprise, name: 'foo') e.name = enterprise.name expect(e).not_to be_valid expect(e.errors[:name].first).to include enterprise_name_error(owner.email) end it "does not prohibit the saving of an enterprise with no name clash" do expect(enterprise).to be_valid end it "sets the enterprise contact to the owner by default" do expect(enterprise.contact).to eq enterprise.owner end end describe "prevent a wrong instagram link pattern" do it "invalidates the instagram attribute https://facebook.com/user" do e = build(:enterprise, instagram: 'https://facebook.com/user') expect(e).not_to be_valid end it "invalidates the instagram attribute tagram.com/user" do e = build(:enterprise, instagram: 'tagram.com/user') expect(e).not_to be_valid end it "invalidates the instagram attribute https://instagram.com/user/preferences" do e = build(:enterprise, instagram: 'https://instagram.com/user/preferences') expect(e).not_to be_valid end it "invalidates the instagram attribute https://www.instagram.com/p/Cpg4McNPyJA/" do e = build(:enterprise, instagram: 'https://www.instagram.com/p/Cpg4McNPyJA/') expect(e).not_to be_valid end it "invalidates the instagram attribute https://instagram.com/user-user" do e = build(:enterprise, instagram: 'https://instagram.com/user-user') expect(e).not_to be_valid end end describe "Verify accepted instagram url pattern" do it "validates empty instagram attribute" do e = build(:enterprise, instagram: '') expect(e).to be_valid expect(e.instagram).to eq "" end it "validates the instagram attribute @my_user" do e = build(:enterprise, instagram: '@my_user') expect(e).to be_valid expect(e.instagram).to eq "my_user" end it "validates the instagram attribute user" do e = build(:enterprise, instagram: 'user') expect(e).to be_valid expect(e.instagram).to eq "user" end it "validates the instagram attribute my_www5.example" do e = build(:enterprise, instagram: 'my_www5.example') expect(e).to be_valid expect(e.instagram).to eq "my_www5.example" end it "validates the instagram attribute http://instagram.com/user" do e = build(:enterprise, instagram: 'http://instagram.com/user') expect(e).to be_valid expect(e.instagram).to eq "user" end it "validates the instagram attribute https://www.instagram.com/user" do e = build(:enterprise, instagram: 'https://www.instagram.com/user') expect(e).to be_valid expect(e.instagram).to eq "user" end it "validates the instagram attribute instagram.com/@user" do e = build(:enterprise, instagram: 'instagram.com/@user') expect(e).to be_valid expect(e.instagram).to eq "user" end it "validates the instagram attribute Https://www.Instagram.com/@User" do e = build(:enterprise, instagram: 'Https://www.Instagram.com/@User') expect(e).to be_valid expect(e.instagram).to eq "user" end it "validates the instagram attribute instagram.com/user" do e = build(:enterprise, instagram: 'instagram.com/user') expect(e).to be_valid expect(e.instagram).to eq "user" end it "renders the expected pattern" do e = build(:enterprise, instagram: 'instagram.com/user') expect(e.instagram).to eq "user" end end describe "preferred_shopfront_message" do it "sanitises HTML" do enterprise = build(:enterprise, preferred_shopfront_message: 'Hello dearest monster.') expect(enterprise.preferred_shopfront_message) .to eq "Hello alert dearest monster." end end describe "preferred_shopfront_closed_message" do it "sanitises HTML" do enterprise = build(:enterprise, preferred_shopfront_closed_message: 'Hello dearest monster.') expect(enterprise.preferred_shopfront_closed_message) .to eq "Hello alert dearest monster." end end describe "preferred_shopfront_taxon_order" do it "empty strings are valid" do enterprise = build(:enterprise, preferred_shopfront_taxon_order: "") expect(enterprise).to be_valid end it "a single integer is valid" do enterprise = build(:enterprise, preferred_shopfront_taxon_order: "11") expect(enterprise).to be_valid end it "comma delimited integers are valid" do enterprise = build(:enterprise, preferred_shopfront_taxon_order: "1,2,3") expect(enterprise).to be_valid enterprise = build(:enterprise, preferred_shopfront_taxon_order: "1,22,333") expect(enterprise).to be_valid end it "commas at the beginning and end are disallowed" do enterprise = build(:enterprise, preferred_shopfront_taxon_order: ",1,2,3") expect(enterprise).not_to be_valid enterprise = build(:enterprise, preferred_shopfront_taxon_order: "1,2,3,") expect(enterprise).not_to be_valid end it "any other characters are invalid" do enterprise = build(:enterprise, preferred_shopfront_taxon_order: "a1,2,3") expect(enterprise).not_to be_valid enterprise = build(:enterprise, preferred_shopfront_taxon_order: ".1,2,3") expect(enterprise).not_to be_valid enterprise = build(:enterprise, preferred_shopfront_taxon_order: " 1,2,3") expect(enterprise).not_to be_valid end end describe "preferred_shopfront_producer_order" do it "empty strings are valid" do enterprise = build(:enterprise, preferred_shopfront_producer_order: "") expect(enterprise).to be_valid end it "a single integer is valid" do enterprise = build(:enterprise, preferred_shopfront_producer_order: "11") expect(enterprise).to be_valid end it "comma delimited integers are valid" do enterprise = build(:enterprise, preferred_shopfront_producer_order: "1,2,3") expect(enterprise).to be_valid enterprise = build(:enterprise, preferred_shopfront_producer_order: "1,22,333") expect(enterprise).to be_valid end it "commas at the beginning and end are disallowed" do enterprise = build(:enterprise, preferred_shopfront_producer_order: ",1,2,3") expect(enterprise).not_to be_valid enterprise = build(:enterprise, preferred_shopfront_producer_order: "1,2,3,") expect(enterprise).not_to be_valid end it "any other characters are invalid" do enterprise = build(:enterprise, preferred_shopfront_producer_order: "a1,2,3") expect(enterprise).not_to be_valid enterprise = build(:enterprise, preferred_shopfront_producer_order: ".1,2,3") expect(enterprise).not_to be_valid enterprise = build(:enterprise, preferred_shopfront_producer_order: " 1,2,3") expect(enterprise).not_to be_valid end end describe "white label logo" do let(:enterprise) { build(:enterprise) } let(:content_type) { 'image/png' } before do blob = instance_double( "ActiveStorage::Blob", filename: ActiveStorage::Filename.new('white-label-logo.png'), content_type:, byte_size: 1024 ) # InstanceDouble is not working for attachment case as the blob method is not yet defined # on instantiation. attachment = double( "ActiveStorage::Attached::One", blank?: false, attached?: true, blob: ) allow(enterprise) .to receive(:white_label_logo).and_return(attachment) end context 'when the file attached is a PNG image' do it 'is valid' do expect(enterprise).to be_valid end end context 'when the file attached is a BMP image' do let(:content_type) { 'image/bmp' } it 'is not valid' do expect(enterprise).not_to be_valid end end it "validates the white_label_logo_link attribute" do enterprise.white_label_logo_link = 'http://www.example.com' expect(enterprise).to be_valid expect(enterprise.white_label_logo_link).to eq "http://www.example.com" end it "adds http:// to the white_label_logo_link attribute if it is missing" do enterprise.white_label_logo_link = 'www.example.com' expect(enterprise).to be_valid expect(enterprise.white_label_logo_link).to eq "http://www.example.com" end it "ignores whitespace around the URL form copying and pasting" do enterprise.white_label_logo_link = ' www.example.com ' expect(enterprise).to be_valid expect(enterprise.white_label_logo_link).to eq "http://www.example.com" end it "does not validate if URL is invalid and can't be infered" do enterprise.white_label_logo_link = 'with spaces' expect(enterprise).not_to be_valid end end describe "external_billing_id" do it "validates the external_billing_id attribute" do e = build(:enterprise, external_billing_id: '123456') expect(e).to be_valid end it "does not validate the external_billing_id attribute with spaces" do e = build(:enterprise, external_billing_id: '123 456') expect(e).not_to be_valid end end end describe "serialisation" do it "sanitises HTML in long_description" do subject.long_description = "Hello dearest monster." expect(subject.long_description).to eq "Hello alert dearest monster." end end describe "callbacks" do describe "restore_permalink" do it "restores permalink to original value when it is changed and invalid" do e1 = create(:enterprise, permalink: "taken") e2 = create(:enterprise, permalink: "not_taken") e2.permalink = "taken" e2.save expect(e2.reload.permalink).to eq "not_taken" end end describe "touch_distributors" do it "touches supplied variant distributors" do enterprise = create(:enterprise) variant = create(:variant) enterprise.supplied_variants << variant updated_at = 1.hour.ago distributor1 = create(:distributor_enterprise, updated_at:) distributor2 = create(:distributor_enterprise, updated_at:) create(:simple_order_cycle, distributors: [distributor1], variants: [variant]) create(:simple_order_cycle, distributors: [distributor2], variants: [variant]) expect { enterprise.touch } .to change { distributor1.reload.updated_at } .and change { distributor2.reload.updated_at } end end end describe "scopes" do describe 'visible' do it 'find visible enterprises' do d1 = create(:distributor_enterprise, visible: false) s1 = create(:supplier_enterprise) expect(Enterprise.visible).to eq([s1]) end end describe "activated" do let!(:unconfirmed_user) { create(:user, confirmed_at: nil, enterprise_limit: 2) } let!(:inactive_enterprise) { create(:enterprise, sells: "unspecified") } let!(:active_enterprise) { create(:enterprise, sells: "none") } it "finds enterprises that have a sells property other than 'unspecified'" do activated_enterprises = Enterprise.activated expect(activated_enterprises).to include active_enterprise expect(activated_enterprises).not_to include inactive_enterprise end end describe "ready_for_checkout" do let!(:e) { create(:enterprise) } it "does not show enterprises with no payment methods" do create(:shipping_method, distributors: [e]) expect(Enterprise.ready_for_checkout).not_to include e end it "does not show enterprises with no shipping methods" do create(:payment_method, distributors: [e]) expect(Enterprise.ready_for_checkout).not_to include e end it "does not show enterprises with unavailable payment methods" do create(:shipping_method, distributors: [e]) create(:payment_method, distributors: [e], active: false) expect(Enterprise.ready_for_checkout).not_to include e end it "does not show enterprises which only have backend shipping methods" do create(:shipping_method, distributors: [e], display_on: Spree::ShippingMethod::DISPLAY_ON_OPTIONS[:back_end]) create(:payment_method, distributors: [e]) expect(Enterprise.ready_for_checkout).not_to include e end it "shows enterprises with available payment and shipping methods" do create(:shipping_method, distributors: [e]) create(:payment_method, distributors: [e]) expect(Enterprise.ready_for_checkout).to include e end end describe "not_ready_for_checkout" do let!(:e) { create(:enterprise) } it "shows enterprises with no payment methods" do create(:shipping_method, distributors: [e]) expect(Enterprise.not_ready_for_checkout).to include e end it "shows enterprises with no shipping methods" do create(:payment_method, distributors: [e]) expect(Enterprise.not_ready_for_checkout).to include e end it "shows enterprises with unavailable payment methods" do create(:shipping_method, distributors: [e]) create(:payment_method, distributors: [e], active: false) expect(Enterprise.not_ready_for_checkout).to include e end it "shows enterprises which only have backend shipping methods" do create(:shipping_method, distributors: [e], display_on: Spree::ShippingMethod::DISPLAY_ON_OPTIONS[:back_end]) create(:payment_method, distributors: [e]) expect(Enterprise.not_ready_for_checkout).to include e end it "does not show enterprises with available payment and shipping methods" do create(:shipping_method, distributors: [e]) create(:payment_method, distributors: [e]) expect(Enterprise.not_ready_for_checkout).not_to include e end end describe "#ready_for_checkout?" do let!(:e) { create(:enterprise) } it "returns false for enterprises with no payment methods" do create(:shipping_method, distributors: [e]) expect(e.reload).not_to be_ready_for_checkout end it "returns false for enterprises with no shipping methods" do create(:payment_method, distributors: [e]) expect(e.reload).not_to be_ready_for_checkout end it "returns false for enterprises with unavailable payment methods" do create(:shipping_method, distributors: [e]) create(:payment_method, distributors: [e], active: false) expect(e.reload).not_to be_ready_for_checkout end it "returns false for enterprises which only have backend shipping methods" do create(:shipping_method, distributors: [e], display_on: Spree::ShippingMethod::DISPLAY_ON_OPTIONS[:back_end]) create(:payment_method, distributors: [e]) expect(e.reload).not_to be_ready_for_checkout end it "returns true for enterprises with available payment and shipping methods" do create(:shipping_method, distributors: [e]) create(:payment_method, distributors: [e]) expect(e.reload).to be_ready_for_checkout end it "returns false for enterprises with payment methods that are available but not configured correctly" do create(:shipping_method, distributors: [e]) create(:stripe_sca_payment_method, distributors: [e]) expect(e.reload).not_to be_ready_for_checkout end end describe "distributors_with_active_order_cycles" do it "finds active distributors by order cycles" do s = create(:supplier_enterprise) d = create(:distributor_enterprise) p = create(:product) create(:simple_order_cycle, suppliers: [s], distributors: [d], variants: [p.variants.first]) expect(Enterprise.distributors_with_active_order_cycles).to eq([d]) end it "should not find inactive distributors by order cycles" do s = create(:supplier_enterprise) d = create(:distributor_enterprise) p = create(:product) create(:simple_order_cycle, orders_open_at: 10.days.from_now, orders_close_at: 17.days.from_now, suppliers: [s], distributors: [d], variants: [p.variants.first]) expect(Enterprise.distributors_with_active_order_cycles).not_to include d end end describe ".supplying_variant_in" do it "finds producers by supply of variant" do supplier = create(:supplier_enterprise) variant = create(:variant, supplier:) expect(Enterprise.supplying_variant_in([variant])).to eq([supplier]) end it "returns multiple enterprises when given multiple variants" do supplier1 = create(:supplier_enterprise) supplier2 = create(:supplier_enterprise) variant1 = create(:variant, supplier: supplier1) variant2 = create(:variant, supplier: supplier2) expect(Enterprise.supplying_variant_in([variant1, variant2])) .to match_array([supplier1, supplier2]) end it "does not return duplicates" do supplier = create(:supplier_enterprise) variant1 = create(:variant, supplier:) variant2 = create(:variant, supplier:) expect(Enterprise.supplying_variant_in([variant1, variant2])).to eq([supplier]) end end describe "distributing_variants" do let(:distributor) { create(:distributor_enterprise) } let(:variant) { create(:variant) } it "returns enterprises distributing via an order cycle" do order_cycle = create(:simple_order_cycle, distributors: [distributor], variants: [variant]) expect(Enterprise.distributing_variants(variant.id)).to eq([distributor]) end it "does not return duplicate enterprises" do another_variant = create(:variant) order_cycle = create(:simple_order_cycle, distributors: [distributor], variants: [variant, another_variant]) expect(Enterprise.distributing_variants( [variant.id, another_variant.id] )).to eq([distributor]) end end describe "managed_by" do it "shows only enterprises for given user" do user = create(:user) e1 = create(:enterprise) e2 = create(:enterprise) e1.enterprise_roles.build(user:).save enterprises = Enterprise.managed_by user expect(enterprises.count).to eq(1) expect(enterprises).to include e1 end it "shows all enterprises for admin user" do user = create(:admin_user) e1 = create(:enterprise) e2 = create(:enterprise) enterprises = Enterprise.managed_by user expect(enterprises.count).to eq(2) expect(enterprises).to include e1 expect(enterprises).to include e2 end end end describe "callbacks" do describe "after creation" do let(:owner) { create(:user, enterprise_limit: 10) } let(:hub1) { create(:distributor_enterprise, owner:) } let(:hub2) { create(:distributor_enterprise, owner:) } let(:hub3) { create(:distributor_enterprise, owner:) } let(:producer1) { create(:supplier_enterprise, owner:) } let(:producer2) { create(:supplier_enterprise, owner:) } describe "when a producer is created" do before do hub1 hub2 end it "creates links from the new producer to all hubs owned by the same user, " \ "granting add_to_order_cycle and create_variant_overrides permissions" do producer1 should_have_enterprise_relationship from: producer1, to: hub1, with: [:add_to_order_cycle, :create_variant_overrides] should_have_enterprise_relationship from: producer1, to: hub2, with: [:add_to_order_cycle, :create_variant_overrides] end it "does not create any other links" do expect do producer1 end.to change { EnterpriseRelationship.count }.by(2) end end describe "when a new hub is created" do it "it creates links to the hub, from all producers owned by the same user, " \ "granting add_to_order_cycle and create_variant_overrides permissions" do producer1 producer2 hub1 should_have_enterprise_relationship from: producer1, to: hub1, with: [:add_to_order_cycle, :create_variant_overrides] should_have_enterprise_relationship from: producer2, to: hub1, with: [:add_to_order_cycle, :create_variant_overrides] end it "creates links from the new hub to all hubs owned by the same user, " \ "granting add_to_order_cycle permission" do hub1 hub2 hub3 should_have_enterprise_relationship from: hub2, to: hub1, with: [:add_to_order_cycle] should_have_enterprise_relationship from: hub3, to: hub1, with: [:add_to_order_cycle] should_have_enterprise_relationship from: hub3, to: hub2, with: [:add_to_order_cycle] end it "does not create any other links" do producer1 producer2 expect { hub1 }.to change { EnterpriseRelationship.count }.by(2) # 2 producer links expect { hub2 }.to change { EnterpriseRelationship.count }.by(3) # 2 producer links + 1 hub link expect { hub3 }.to change { EnterpriseRelationship.count }.by(4) # 2 producer links + 2 hub links end end def should_have_enterprise_relationship(opts = {}) er = EnterpriseRelationship.where(parent_id: opts[:from], child_id: opts[:to]).last expect(er).not_to be_nil if opts[:with] == :all_permissions expect(er.permissions.map(&:name)).to match_array ['add_to_order_cycle', 'manage_products', 'edit_profile', 'create_variant_overrides'] elsif opts.key? :with expect(er.permissions.map(&:name)).to match_array opts[:with].map(&:to_s) end end end end describe "finding variants distributed by the enterprise" do it "finds variants distributed by order cycle" do distributor = create(:distributor_enterprise) product = create(:product) variant = product.variants.first create(:simple_order_cycle, distributors: [distributor], variants: [variant]) expect(distributor.distributed_variants).to match_array [variant] end end describe "taxons" do let(:distributor) { create(:distributor_enterprise) } let(:supplier) { create(:supplier_enterprise) } let(:taxon1) { create(:taxon) } let(:taxon2) { create(:taxon) } let(:taxon3) { create(:taxon) } let(:product1) { create(:simple_product, primary_taxon: taxon1) } let(:product2) { create(:simple_product, primary_taxon: taxon2) } let(:product3) { create(:simple_product, primary_taxon: taxon3) } let(:oc) { create(:order_cycle) } let(:ex) { create(:exchange, order_cycle: oc, incoming: false, sender: supplier, receiver: distributor) } it "gets all taxons of all distributed products" do allow(Spree::Product).to receive(:in_distributor).and_return [product1, product2] expect(distributor.distributed_taxons).to match_array [taxon1, taxon2] end it "gets all taxons of all distributed products in open order cycles" do allow(Spree::Product).to receive(:in_distributor).and_return [product1, product2, product3] ex.variants << product1.variants.first ex.variants << product3.variants.first expect(distributor.current_distributed_taxons).to match_array [taxon1, taxon3] end it "gets all taxons of all supplied products" do allow(Spree::Product).to receive(:in_supplier).and_return [product1, product2] expect(supplier.supplied_taxons).to match_array [taxon1, taxon2] end end describe "presentation of attributes" do let(:distributor) { build_stubbed(:distributor_enterprise, website: "http://www.google.com", facebook: "www.facebook.com/roger", linkedin: "https://linkedin.com", instagram: "https://www.instagram.com/@insgram_user", twitter: "www.twitter.com/@twitter_user") } it "strips http from url fields" do expect(distributor.website).to eq("www.google.com") expect(distributor.facebook).to eq("www.facebook.com/roger") expect(distributor.linkedin).to eq("linkedin.com") end it "strips @, http and domain address from url fields" do expect(distributor.instagram).to eq("insgram_user") expect(distributor.twitter).to eq("twitter_user") end end describe "producer properties" do let(:supplier) { create(:supplier_enterprise) } it "sets producer properties" do supplier.set_producer_property 'Organic Certified', 'NASAA 12345' expect(supplier.producer_properties.count).to eq(1) expect(supplier.producer_properties.first.value).to eq('NASAA 12345') expect(supplier.producer_properties.first.property.presentation).to eq('Organic Certified') end end describe "provide enterprise category" do let(:producer_sell_all) { build_stubbed(:enterprise, is_primary_producer: true, sells: "any") } let(:producer_sell_own) { build_stubbed(:enterprise, is_primary_producer: true, sells: "own") } let(:producer_sell_none) { build_stubbed(:enterprise, is_primary_producer: true, sells: "none") } let(:non_producer_sell_all) { build_stubbed(:enterprise, is_primary_producer: false, sells: "any") } let(:non_producer_sell_own) { build_stubbed(:enterprise, is_primary_producer: false, sells: "own") } let(:non_producer_sell_none) { build_stubbed(:enterprise, is_primary_producer: false, sells: "none") } it "should output enterprise categories" do expect(producer_sell_all.is_primary_producer).to eq(true) expect(producer_sell_all.sells).to eq("any") expect(producer_sell_all.category).to eq(:producer_hub) expect(producer_sell_own.category).to eq(:producer_shop) expect(producer_sell_none.category).to eq(:producer) expect(non_producer_sell_all.category).to eq(:hub) expect(non_producer_sell_own.category).to eq(:hub) expect(non_producer_sell_none.category).to eq(:hub_profile) end end describe "finding and automatically assigning a permalink" do let(:enterprise) { build_stubbed(:enterprise, name: "Name To Turn Into A Permalink") } it "assigns permalink when initialized" do allow(Enterprise).to receive(:find_available_permalink).and_return("available_permalink") expect(Enterprise).to receive(:find_available_permalink).with("Name To Turn Into A Permalink") expect do enterprise.__send__(:initialize_permalink) end.to change { enterprise.permalink }.to("available_permalink") end describe "finding a permalink" do let!(:enterprise1) { create(:enterprise, permalink: "permalink") } let!(:enterprise2) { create(:enterprise, permalink: "permalink1") } it "parameterizes the value provided" do expect(Enterprise.find_available_permalink("Some Unused Permalink")) .to eq "some-unused-permalink" end it "sets the permalink to 'my-enterprise' if parametized permalink is blank" do expect(Enterprise.find_available_permalink("")).to eq "my-enterprise" expect(Enterprise.find_available_permalink("$$%{$**}$%}")).to eq "my-enterprise" end it "finds and index value based on existing permalinks" do expect(Enterprise.find_available_permalink("permalink")).to eq "permalink2" end it "ignores permalinks with characters after the index value" do create(:enterprise, permalink: "permalink2xxx") expect(Enterprise.find_available_permalink("permalink")).to eq "permalink2" end it "finds available permalink similar to existing" do create(:enterprise, permalink: "permalink2xxx") expect(Enterprise.find_available_permalink("permalink2")).to eq "permalink2" end it "finds gaps in the indices of existing permalinks" do create(:enterprise, permalink: "permalink3") expect(Enterprise.find_available_permalink("permalink")).to eq "permalink2" end it "should support permalink generation from names with non-roman characters" do enterprise = create(:enterprise, name: "你好") expect(enterprise.valid?).to be true expect(enterprise.permalink).to eq "ni-hao" end end end describe "#parents_of_one_union_others" do it "should return only parent producers" do supplier = create(:supplier_enterprise) distributor = create(:distributor_enterprise, is_primary_producer: false) permission = EnterpriseRelationshipPermission.new(name: "add_to_order_cycle") create(:enterprise_relationship, parent: distributor, child: supplier, permissions: [permission]) expect(Enterprise.parents_of_one_union_others(supplier, nil)).to include(distributor) end it "should return other enterprise if it is passed as a second argument" do another_enterprise = create(:enterprise) supplier = create(:supplier_enterprise) distributor = create(:distributor_enterprise, is_primary_producer: false) permission = EnterpriseRelationshipPermission.new(name: "add_to_order_cycle") create(:enterprise_relationship, parent: distributor, child: supplier, permissions: [permission]) expect( Enterprise.parents_of_one_union_others(supplier, another_enterprise) ).to include(another_enterprise) end it "does not find child in the relationship" do supplier = create(:supplier_enterprise) distributor = create(:distributor_enterprise, is_primary_producer: false) permission = EnterpriseRelationshipPermission.new(name: "add_to_order_cycle") create(:enterprise_relationship, parent: distributor, child: supplier, permissions: [permission]) expect(Enterprise.parents_of_one_union_others(distributor, nil)).not_to include(supplier) end end describe "#plus_parents_and_order_cycle_producers" do it "does not find non-producers" do supplier = create(:supplier_enterprise) distributor = create(:distributor_enterprise, is_primary_producer: false) product = create(:product) order_cycle = create( :simple_order_cycle, suppliers: [supplier], distributors: [distributor], variants: [product.variants.first] ) expect(distributor.plus_parents_and_order_cycle_producers(order_cycle)).to eq([supplier]) end it "finds parent in the relationship" do supplier = create(:supplier_enterprise) distributor = create(:distributor_enterprise, is_primary_producer: false) permission = EnterpriseRelationshipPermission.new(name: "add_to_order_cycle") product = create(:product) order_cycle = create( :simple_order_cycle, distributors: [distributor], suppliers: [supplier], variants: [product.variants.first] ) create(:enterprise_relationship, parent: distributor, child: supplier, permissions: [permission]) expect(distributor.plus_parents_and_order_cycle_producers(order_cycle)).to include(supplier) end it "does not find child in the relationship" do supplier = create(:supplier_enterprise) distributor = create(:distributor_enterprise, is_primary_producer: false) permission = EnterpriseRelationshipPermission.new(name: "add_to_order_cycle") create(:enterprise_relationship, parent: distributor, child: supplier, permissions: [permission]) product = create(:product) order_cycle = create( :simple_order_cycle, suppliers: [supplier], distributors: [distributor], variants: [product.variants.first] ) expected = supplier.plus_parents_and_order_cycle_producers(order_cycle) expect(expected).not_to include(distributor) end it "it finds sender enterprises for order cycles that are passed" do supplier = create(:supplier_enterprise) sender = create(:supplier_enterprise) distributor = create(:distributor_enterprise, is_primary_producer: false) permission = EnterpriseRelationshipPermission.new(name: "add_to_order_cycle") create(:enterprise_relationship, parent: distributor, child: supplier, permissions: [permission]) product = create(:product) order_cycle = create( :simple_order_cycle, suppliers: [sender], distributors: [distributor], variants: [product.variants.first] ) expected = supplier.plus_parents_and_order_cycle_producers(order_cycle) expect(expected).to include(sender) end end describe "#is_producer_only" do context "when enterprise is_primary_producer and sells none" do it "returns true" do enterprise = build(:supplier_enterprise) expect(enterprise.is_producer_only).to be true end end context "when enterprise is_primary_producer and sells any" do it "returns false" do enterprise = build(:enterprise, is_primary_producer: true, sells: "any") expect(enterprise.is_producer_only).to be false end end context "when enterprise is_primary_producer and sells own" do it "returns false" do enterprise = build(:enterprise, is_primary_producer: true, sells: "own") expect(enterprise.is_producer_only).to be false end end end end def enterprise_name_error(owner_email) "has already been taken. \ If this is your enterprise and you would like to claim ownership, \ or if you would like to trade with this enterprise please contact \ the current manager of this profile at %s." % owner_email end