Files
openfoodnetwork/spec/models/enterprise_spec.rb
Gaetan Craig-Riou bc23423521 Remove the link between enterprise and internal payment method
Enterprise have access to the internal payment method by default.
The access is handled at the application level so we don't have to
manage database links.
2026-03-10 16:07:43 +11:00

1117 lines
42 KiB
Ruby

# frozen_string_literal: true
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 <script>alert</script> dearest <b>monster</b>.')
expect(enterprise.preferred_shopfront_message)
.to eq "Hello alert dearest <b>monster</b>."
end
end
describe "preferred_shopfront_closed_message" do
it "sanitises HTML" do
enterprise = build(:enterprise, preferred_shopfront_closed_message:
'Hello <script>alert</script> dearest <b>monster</b>.')
expect(enterprise.preferred_shopfront_closed_message)
.to eq "Hello alert dearest <b>monster</b>."
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 = Rack::Test::UploadedFile.new('spec/fixtures/files/logo.png', content_type)
enterprise.white_label_logo.attach(blob)
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' }
before do
blob = Rack::Test::UploadedFile.new('spec/fixtures/files/logo.bmp', content_type)
enterprise.white_label_logo.attach(blob)
end
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 <script>alert</script> dearest <b>monster</b>."
expect(subject.long_description).to eq "Hello alert dearest <b>monster</b>."
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
describe "#contact_id" do
it "returns the ID of the enterprise's contact" do
enterprise = build(:enterprise)
expect(enterprise.contact_id).to eq(enterprise.contact.id)
end
end
describe "#contact_id=" do
let(:enterprise) { create(:enterprise) }
it "accepts confirmed users that belongs to the enterprise" do
user = create(:user, confirmed_at: Time.now.utc)
enterprise.enterprise_roles.create!(user: user)
enterprise.contact_id = user.id
expect(enterprise.contact).to eq(user)
end
it "rejects users that don't belong to the enterprise" do
user = create(:user, confirmed_at: Time.now.utc)
enterprise.contact_id = user.id
expect(enterprise.contact).not_to eq(user)
end
it "rejects unconfirmed users" do
user = create(:user, confirmed_at: nil)
enterprise.enterprise_roles.create!(user: user)
enterprise.contact_id = user.id
expect(enterprise.contact).not_to eq(user)
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