# frozen_string_literal: true require 'spec_helper' RSpec.describe Spree::ShippingMethod do it "is valid when built from factory" do expect( build( :shipping_method, shipping_categories: [Spree::ShippingCategory.new(name: 'Test')] ) ).to be_valid end it "can have distributors" do d1 = create(:distributor_enterprise) d2 = create(:distributor_enterprise) sm = create(:shipping_method) sm.distributors.clear sm.distributors << d1 sm.distributors << d2 expect(sm.reload.distributors).to match_array [d1, d2] end describe "scope" do describe "filtering to specified distributors" do let!(:distributor_a) { create(:distributor_enterprise) } let!(:distributor_b) { create(:distributor_enterprise) } let!(:distributor_c) { create(:distributor_enterprise) } let!(:shipping_method_a) { create(:shipping_method, distributors: [distributor_a, distributor_b]) } let!(:shipping_method_b) { create(:shipping_method, distributors: [distributor_b]) } let!(:shipping_method_c) { create(:shipping_method, distributors: [distributor_c]) } it "includes only unique records under specified distributors" do result = described_class.for_distributors([distributor_a, distributor_b]) expect(result.length).to eq(2) expect(result).to include(shipping_method_a) expect(result).to include(shipping_method_b) end end it "finds shipping methods for a particular distributor" do d1 = create(:distributor_enterprise) d2 = create(:distributor_enterprise) sm1 = create(:shipping_method, distributors: [d1]) sm2 = create(:shipping_method, distributors: [d2]) expect(described_class.for_distributor(d1)).to eq([sm1]) end end it "orders shipping methods by name" do sm1 = create(:shipping_method, name: 'ZZ') sm2 = create(:shipping_method, name: 'AA') sm3 = create(:shipping_method, name: 'BB') expect(described_class.by_name).to eq([sm2, sm3, sm1]) end describe "finding services offered by all distributors" do let!(:d1) { create(:distributor_enterprise) } let!(:d2) { create(:distributor_enterprise) } let!(:d3) { create(:distributor_enterprise) } let!(:d4) { create(:distributor_enterprise) } let!(:d1_pickup) { create(:shipping_method, require_ship_address: false, distributors: [d1]) } let!(:d1_delivery) { create(:shipping_method, require_ship_address: true, distributors: [d1]) } let!(:d2_pickup) { create(:shipping_method, require_ship_address: false, distributors: [d2]) } let!(:d3_delivery) { create(:shipping_method, require_ship_address: true, distributors: [d3]) } it "reports when the services are available" do expect(described_class.services[d1.id]).to eq(pickup: true, delivery: true) end it "reports when only pickup is available" do expect(described_class.services[d2.id]).to eq(pickup: true, delivery: false) end it "reports when only delivery is available" do expect(described_class.services[d3.id]).to eq(pickup: false, delivery: true) end it "returns no entry when no service is available" do expect(described_class.services[d4.id]).to be_nil end end describe '#delivery?' do context 'when the shipping method requires an address' do let(:shipping_method) { build(:shipping_method, require_ship_address: true) } it { expect(shipping_method.delivery?).to be true } end context 'when the shipping method does not require address' do let(:shipping_method) { build(:shipping_method, require_ship_address: false) } it { expect(shipping_method.delivery?).to be false } end end describe "#delivers_to?" do let(:shipping_method) { build_stubbed(:shipping_method) } it "does not deliver to a nil address" do expect(shipping_method.delivers_to?(nil)).to be false end it "includes an address that is not included in the zones of the shipping method" do address = create(:address) zone_mock = instance_double(Spree::Zone) allow(zone_mock).to receive(:contains?).with(address).and_return(false) allow(shipping_method).to receive(:zones) { [zone_mock] } expect(shipping_method.delivers_to?(address)).to be true end end describe "touches" do let!(:distributor) { create(:distributor_enterprise) } let!(:shipping_method) { create(:shipping_method) } let(:add_distributor) { shipping_method.distributors << distributor } it "is touched when applied to a distributor" do expect{ add_distributor }.to change { shipping_method.reload.updated_at } end end context "validations" do it "validates presence of name" do shipping_method = build_stubbed( :shipping_method, name: '' ) expect(shipping_method).not_to be_valid expect(shipping_method.errors[:name].first).to eq "can't be blank" end describe "#display_on" do it "is valid when it's set to nil, an empty string or 'back_end'" do shipping_method = build_stubbed( :shipping_method, shipping_categories: [Spree::ShippingCategory.new(name: 'Test')] ) [nil, "", "back_end"].each do |display_on_option| shipping_method.display_on = display_on_option expect(shipping_method).to be_valid end end it "is not valid when it's set to an unknown value" do shipping_method = build_stubbed(:shipping_method, display_on: "front_end") expect(shipping_method).not_to be_valid expect(shipping_method.errors[:display_on]).to eq ["is not included in the list"] end end context "shipping category" do it "validates presence of at least one" do shipping_method = build_stubbed( :shipping_method, shipping_categories: [] ) expect(shipping_method).not_to be_valid expect(shipping_method.errors[:base].first) .to eq "You need to select at least one shipping category" end context "one associated" do let(:shipping_method) do build_stubbed( :shipping_method, shipping_categories: [Spree::ShippingCategory.new(name: 'Test')] ) end it { expect(shipping_method).to be_valid } end end end # Regression test for Spree #4320 context "soft deletion" do let(:shipping_method) { create(:shipping_method) } it "soft-deletes when destroy is called" do shipping_method.destroy expect(shipping_method.deleted_at).not_to be_blank end end context 'factory' do let(:shipping_method){ create :shipping_method } it "should set calculable correctly" do expect(shipping_method.calculator.calculable).to eq(shipping_method) end end # Regression test for Spree #4492 context "#shipments" do let!(:shipping_method) { create(:shipping_method) } let!(:shipment) do shipment = create(:shipment) shipment.shipping_rates.create!(shipping_method:) shipment end it "can gather all the related shipments" do expect(shipping_method.shipments).to include(shipment) end end end