Files
openfoodnetwork/spec/models/enterprise_spec.rb
fabricio.albarnaz 8e4adbd23a Add more test cases
2018-10-16 15:34:46 -03:00

708 lines
26 KiB
Ruby

require 'spec_helper'
describe Enterprise do
include AuthenticationWorkflow
describe "sending emails" do
describe "on creation" do
let!(:user) { create_enterprise_user( enterprise_limit: 2 ) }
let!(:enterprise) { create(:enterprise, owner: user) }
it "sends a welcome email" do
expect do
create(:enterprise, owner: user)
end.to enqueue_job WelcomeEnterpriseJob
end
end
end
describe "associations" do
it { should belong_to(:owner) }
it { should have_many(:supplied_products) }
it { should have_many(:distributed_orders) }
it { should belong_to(:address) }
it { should have_many(:product_distributions) }
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
EnterpriseRole.where(id: role.id).should be_empty
end
it "destroys supplied products upon destroy" do
s = create(:supplier_enterprise)
p = create(:simple_product, supplier: s)
s.destroy
Spree::Product.where(id: p.id).should 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
EnterpriseRelationship.where(id: [er1, er2]).should be_empty
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
e.relatives.should 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
e.should_receive(:relatives_including_self).and_return(relatives = [])
relatives.should_receive(:is_distributor).and_return relatives
e.distributors
end
it "scopes relatives to visible producers" do
e.should_receive(:relatives_including_self).and_return(relatives = [])
relatives.should_receive(:is_primary_producer).and_return relatives
e.suppliers
end
end
describe "ownership" do
let(:u1) { create_enterprise_user }
let(:u2) { create_enterprise_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).to_not 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
subject { FactoryBot.create(:distributor_enterprise) }
it { should validate_presence_of(:name) }
it { should validate_uniqueness_of(:permalink) }
it { should ensure_length_of(:description).is_at_most(255) }
it "requires an owner" do
expect{
e = create(:enterprise, owner: nil)
}.to raise_error ActiveRecord::RecordInvalid, "Validation failed: Owner can't be blank"
end
describe "name uniqueness" do
let(:owner) { create(:user, email: 'owner@example.com') }
let!(:enterprise) { create(:enterprise, name: 'Enterprise', owner: owner) }
it "prevents duplicate names for new records" do
e = Enterprise.new name: enterprise.name
expect(e).to_not be_valid
expect(e.errors[:name].first).to include I18n.t('enterprise_name_error', email: owner.email)
end
it "prevents duplicate names for existing records" do
e = create(:enterprise, name: 'foo')
e.name = enterprise.name
expect(e).to_not be_valid
expect(e.errors[:name].first).to include I18n.t('enterprise_name_error', email: owner.email)
end
it "does not prohibit the saving of an enterprise with no name clash" do
enterprise.should be_valid
end
it "sets the enterprise contact to the owner by default" do
enterprise.contact.should eq enterprise.owner
end
context "prevent an wrong instagram link pattern" do
it "expects to be invalid the instagram attribute @my-user" do
e = build(:enterprise, instagram: '@my-user')
expect(e).to_not be_valid
end
it "expects to be invalid the instagram attribute https://facebook.com/user" do
e = build(:enterprise, instagram: 'https://facebook.com/user')
expect(e).to_not be_valid
end
it "expects to be invalid the instagram attribute tagram.com/user" do
e = build(:enterprise, instagram: 'tagram.com/user')
expect(e).to_not be_valid
end
it "expects to be invalid the instagram attribute https://instagram.com/user/preferences" do
e = build(:enterprise, instagram: 'https://instagram.com/user/preferences')
expect(e).to_not be_valid
end
end
context "accepted pattern" do
it "expects to be valid empty instagram attribute" do
e = build(:enterprise)
expect(e).to be_valid
end
it "expects be valid the instagram attribute @user" do
e = build(:enterprise, instagram: '@user')
expect(e).to be_valid
end
it "expects be valid the instagram attribute @my_www5.example" do
e = build(:enterprise, instagram: '@my_www5.example')
expect(e).to be_valid
end
it "expects be valid the instagram attribute http://instagram.com/user" do
e = build(:enterprise, instagram: 'http://instagram.com/user')
expect(e).to be_valid
end
it "expects be valid the instagram attribute https://instagram.com/user/" do
e = build(:enterprise, instagram: 'https://instagram.com/user/')
expect(e).to be_valid
end
it "expects be valid the instagram attribute https://www.instagram.com/user" do
e = build(:enterprise, instagram: 'https://www.instagram.com/user')
expect(e).to be_valid
end
it "expects be valid the instagram attribute instagram.com/user" do
e = build(:enterprise, instagram: 'instagram.com/user')
expect(e).to be_valid
end
it "renders the expected pattern" do
e = build(:enterprise, instagram: 'instagram.com/user')
expect(e.instagram).to eq('@user')
end
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).to be_invalid
enterprise = build(:enterprise, preferred_shopfront_taxon_order: "1,2,3,")
expect(enterprise).to be_invalid
end
it "any other characters are invalid" do
enterprise = build(:enterprise, preferred_shopfront_taxon_order: "a1,2,3")
expect(enterprise).to be_invalid
enterprise = build(:enterprise, preferred_shopfront_taxon_order: ".1,2,3")
expect(enterprise).to be_invalid
enterprise = build(:enterprise, preferred_shopfront_taxon_order: " 1,2,3")
expect(enterprise).to be_invalid
end
end
end
describe "delegations" do
#subject { FactoryBot.create(:distributor_enterprise, :address => FactoryBot.create(:address)) }
it { should delegate(:latitude).to(:address) }
it { should delegate(:longitude).to(:address) }
it { should delegate(:city).to(:address) }
it { should delegate(:state_name).to(:address) }
end
describe "callbacks" 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.permalink).to eq "not_taken"
end
end
describe "scopes" do
describe 'visible' do
it 'find visible enterprises' do
d1 = create(:distributor_enterprise, visible: false)
s1 = create(:supplier_enterprise)
Enterprise.visible.should == [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).to_not 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])
Enterprise.ready_for_checkout.should_not include e
end
it "does not show enterprises with no shipping methods" do
create(:payment_method, distributors: [e])
Enterprise.ready_for_checkout.should_not 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)
Enterprise.ready_for_checkout.should_not include e
end
it "shows enterprises with available payment and shipping methods" do
create(:shipping_method, distributors: [e])
create(:payment_method, distributors: [e])
Enterprise.ready_for_checkout.should 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])
Enterprise.not_ready_for_checkout.should include e
end
it "shows enterprises with no shipping methods" do
create(:payment_method, distributors: [e])
Enterprise.not_ready_for_checkout.should include e
end
it "shows enterprises with unavailable payment methods" do
create(:shipping_method, distributors: [e])
create(:payment_method, distributors: [e], active: false)
Enterprise.not_ready_for_checkout.should 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])
Enterprise.not_ready_for_checkout.should_not 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])
e.reload.should_not be_ready_for_checkout
end
it "returns false for enterprises with no shipping methods" do
create(:payment_method, distributors: [e])
e.reload.should_not 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)
e.reload.should_not 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])
e.reload.should 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.master])
Enterprise.distributors_with_active_order_cycles.should == [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.master])
Enterprise.distributors_with_active_order_cycles.should_not include d
end
end
describe "supplying_variant_in" do
it "finds producers by supply of master variant" do
s = create(:supplier_enterprise)
p = create(:simple_product, supplier: s)
Enterprise.supplying_variant_in([p.master]).should == [s]
end
it "finds producers by supply of variant" do
s = create(:supplier_enterprise)
p = create(:simple_product, supplier: s)
v = create(:variant, product: p)
Enterprise.supplying_variant_in([v]).should == [s]
end
it "returns multiple enterprises when given multiple variants" do
s1 = create(:supplier_enterprise)
s2 = create(:supplier_enterprise)
p1 = create(:simple_product, supplier: s1)
p2 = create(:simple_product, supplier: s2)
Enterprise.supplying_variant_in([p1.master, p2.master]).should match_array [s1, s2]
end
it "does not return duplicates" do
s = create(:supplier_enterprise)
p1 = create(:simple_product, supplier: s)
p2 = create(:simple_product, supplier: s)
Enterprise.supplying_variant_in([p1.master, p2.master]).should == [s]
end
end
describe "distributing_products" do
it "returns enterprises distributing via a product distribution" do
d = create(:distributor_enterprise)
p = create(:product, distributors: [d])
Enterprise.distributing_products(p).should == [d]
end
it "returns enterprises distributing via an order cycle" do
d = create(:distributor_enterprise)
p = create(:product)
oc = create(:simple_order_cycle, distributors: [d], variants: [p.master])
Enterprise.distributing_products(p).should == [d]
end
it "returns enterprises distributing via a product distribution" do
d = create(:distributor_enterprise)
p = create(:product, distributors: [d])
Enterprise.distributing_products([p]).should == [d]
end
it "returns enterprises distributing via an order cycle" do
d = create(:distributor_enterprise)
p = create(:product)
oc = create(:simple_order_cycle, distributors: [d], variants: [p.master])
Enterprise.distributing_products([p]).should == [d]
end
it "does not return duplicate enterprises" do
d = create(:distributor_enterprise)
p1 = create(:product, distributors: [d])
p2 = create(:product, distributors: [d])
Enterprise.distributing_products([p1, p2]).should == [d]
end
end
describe "managed_by" do
it "shows only enterprises for given user" do
user = create(:user)
user.spree_roles = []
e1 = create(:enterprise)
e2 = create(:enterprise)
e1.enterprise_roles.build(user: user).save
enterprises = Enterprise.managed_by user
enterprises.count.should == 1
enterprises.should 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
enterprises.count.should == 2
enterprises.should include e1
enterprises.should 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: owner) }
let(:hub2) { create(:distributor_enterprise, owner: owner) }
let(:hub3) { create(:distributor_enterprise, owner: owner) }
let(:producer1) { create(:supplier_enterprise, owner: owner) }
let(:producer2) { create(:supplier_enterprise, owner: 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
er.should_not be_nil
if opts[:with] == :all_permissions
er.permissions.map(&:name).should match_array ['add_to_order_cycle', 'manage_products', 'edit_profile', 'create_variant_overrides']
elsif opts.key? :with
er.permissions.map(&:name).should match_array opts[:with].map(&:to_s)
end
end
end
end
describe "finding variants distributed by the enterprise" do
it "finds master and other variants" do
d = create(:distributor_enterprise)
p = create(:product, distributors: [d])
v = p.variants.first
d.distributed_variants.should match_array [p.master, v]
end
pending "finds variants distributed by order cycle" do
# there isn't actually a method for this on Enterprise?
d = create(:distributor_enterprise)
p = create(:product)
v = p.variants.first
oc = create(:simple_order_cycle, distributors: [d], variants: [v])
# This method doesn't do what this test says it does...
d.distributed_variants.should match_array [v]
end
end
describe "finding variants distributed by the enterprise in a product distribution only" do
it "finds master and other variants" do
d = create(:distributor_enterprise)
p = create(:product, distributors: [d])
v = p.variants.first
d.product_distribution_variants.should match_array [p.master, v]
end
it "does not find variants distributed by order cycle" do
d = create(:distributor_enterprise)
p = create(:product)
v = p.variants.first
oc = create(:simple_order_cycle, distributors: [d], variants: [v])
d.product_distribution_variants.should == []
end
end
describe "taxons" do
let(:distributor) { create(:distributor_enterprise) }
let(:supplier) { create(:supplier_enterprise) }
let(:taxon1) { create(:taxon) }
let(:taxon2) { create(:taxon) }
let(:product1) { create(:simple_product, primary_taxon: taxon1, taxons: [taxon1]) }
let(:product2) { create(:simple_product, primary_taxon: taxon1, taxons: [taxon1, taxon2]) }
it "gets all taxons of all distributed products" do
Spree::Product.stub(:in_distributor).and_return [product1, product2]
distributor.distributed_taxons.should match_array [taxon1, taxon2]
end
it "gets all taxons of all supplied products" do
Spree::Product.stub(:in_supplier).and_return [product1, product2]
supplier.supplied_taxons.should match_array [taxon1, taxon2]
end
end
describe "presentation of attributes" do
let(:distributor) {
create(:distributor_enterprise,
website: "http://www.google.com",
facebook: "www.facebook.com/roger",
linkedin: "https://linkedin.com")
}
it "strips http from url fields" do
distributor.website.should == "www.google.com"
distributor.facebook.should == "www.facebook.com/roger"
distributor.linkedin.should == "linkedin.com"
end
end
describe "producer properties" do
let(:supplier) { create(:supplier_enterprise) }
it "sets producer properties" do
supplier.set_producer_property 'Organic Certified', 'NASAA 12345'
supplier.producer_properties.count.should == 1
supplier.producer_properties.first.value.should == 'NASAA 12345'
supplier.producer_properties.first.property.presentation.should == 'Organic Certified'
end
end
describe "provide enterprise category" do
let(:producer_sell_all) { build(:enterprise, is_primary_producer: true, sells: "any") }
let(:producer_sell_own) { build(:enterprise, is_primary_producer: true, sells: "own") }
let(:producer_sell_none) { build(:enterprise, is_primary_producer: true, sells: "none") }
let(:non_producer_sell_all) { build(:enterprise, is_primary_producer: false, sells: "any") }
let(:non_producer_sell_own) { build(:enterprise, is_primary_producer: false, sells: "own") }
let(:non_producer_sell_none) { build(:enterprise, is_primary_producer: false, sells: "none") }
it "should output enterprise categories" do
producer_sell_all.is_primary_producer.should == true
producer_sell_all.sells.should == "any"
producer_sell_all.category.should == :producer_hub
producer_sell_own.category.should == :producer_shop
producer_sell_none.category.should == :producer
non_producer_sell_all.category.should == :hub
non_producer_sell_own.category.should == :hub
non_producer_sell_none.category.should == :hub_profile
end
end
describe "finding and automatically assigning a permalink" do
let(:enterprise) { build(: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")
Enterprise.should_receive(:find_available_permalink).with("Name To Turn Into A Permalink")
expect(
lambda { enterprise.send(:initialize_permalink) }
).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
end
end
end