solidus_core 2.1.1 → 2.2.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of solidus_core might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Rakefile +0 -1
- data/app/assets/config/solidus_core_manifest.js +1 -0
- data/app/assets/javascripts/spree.js.erb +72 -0
- data/app/helpers/spree/store_helper.rb +5 -0
- data/app/jobs/spree/promotion_code_batch_job.rb +24 -0
- data/app/mailers/spree/promotion_code_batch_mailer.rb +13 -0
- data/app/models/concerns/spree/calculated_adjustments.rb +1 -1
- data/app/models/concerns/spree/ordered_property_value_list.rb +2 -2
- data/app/models/concerns/spree/user_address_book.rb +4 -4
- data/app/models/concerns/spree/user_methods.rb +7 -0
- data/app/models/concerns/spree/user_payment_source.rb +12 -5
- data/app/models/spree/address.rb +14 -3
- data/app/models/spree/adjustment.rb +13 -1
- data/app/models/spree/app_configuration.rb +0 -19
- data/app/models/spree/base.rb +2 -0
- data/app/models/spree/credit_card.rb +34 -43
- data/app/models/spree/gateway/bogus.rb +1 -1
- data/app/models/spree/gateway.rb +6 -4
- data/app/models/spree/inventory_unit.rb +3 -2
- data/app/models/spree/order/checkout.rb +187 -273
- data/app/models/spree/order.rb +137 -71
- data/app/models/spree/order_contents.rb +1 -1
- data/app/models/spree/order_inventory.rb +11 -11
- data/app/models/spree/order_promotion.rb +2 -0
- data/app/models/spree/order_update_attributes.rb +1 -8
- data/app/models/spree/order_updater.rb +67 -63
- data/app/models/spree/payment.rb +0 -1
- data/app/models/spree/payment_create.rb +27 -7
- data/app/models/spree/payment_method/store_credit.rb +3 -3
- data/app/models/spree/payment_method.rb +4 -1
- data/app/models/spree/payment_source.rb +45 -0
- data/app/models/spree/product/scopes.rb +24 -24
- data/app/models/spree/product.rb +4 -4
- data/app/models/spree/promotion.rb +2 -0
- data/app/models/spree/promotion_code/batch_builder.rb +63 -0
- data/app/models/spree/promotion_code.rb +1 -0
- data/app/models/spree/promotion_code_batch.rb +25 -0
- data/app/models/spree/promotion_handler/cart.rb +2 -2
- data/app/models/spree/promotion_handler/coupon.rb +1 -2
- data/app/models/spree/promotion_handler/free_shipping.rb +32 -21
- data/app/models/spree/promotion_handler/page.rb +1 -1
- data/app/models/spree/reimbursement.rb +1 -1
- data/app/models/spree/return_authorization.rb +0 -28
- data/app/models/spree/return_item.rb +1 -1
- data/app/models/spree/shipment.rb +4 -4
- data/app/models/spree/shipping_method.rb +2 -2
- data/app/models/spree/shipping_rate.rb +1 -1
- data/app/models/spree/stock/availability_validator.rb +16 -17
- data/app/models/spree/stock/coordinator.rb +3 -3
- data/app/models/spree/stock/package.rb +1 -1
- data/app/models/spree/stock/quantifier.rb +5 -4
- data/app/models/spree/stock_location.rb +2 -2
- data/app/models/spree/store.rb +2 -2
- data/app/models/spree/store_credit.rb +1 -1
- data/app/models/spree/tax/tax_helpers.rb +3 -3
- data/app/models/spree/tax_rate.rb +7 -1
- data/app/models/spree/taxonomy.rb +1 -1
- data/app/models/spree/variant/scopes.rb +5 -5
- data/app/models/spree/variant/vat_price_generator.rb +8 -5
- data/app/models/spree/variant.rb +1 -0
- data/app/models/spree/wallet/add_payment_sources_to_wallet.rb +19 -10
- data/app/models/spree/wallet/default_payment_builder.rb +6 -6
- data/app/models/spree/wallet.rb +71 -0
- data/app/models/spree/wallet_payment_source.rb +17 -0
- data/app/models/spree/zone.rb +1 -1
- data/app/views/spree/carton_mailer/shipped_email.text.erb +1 -1
- data/app/views/spree/promotion_code_batch_mailer/promotion_code_batch_errored.text.erb +2 -0
- data/app/views/spree/promotion_code_batch_mailer/promotion_code_batch_finished.text.erb +2 -0
- data/app/views/spree/reimbursement_mailer/reimbursement_email.html.erb +0 -7
- data/app/views/spree/reimbursement_mailer/reimbursement_email.text.erb +0 -5
- data/app/views/spree/shared/_error_messages.html.erb +1 -1
- data/app/views/spree/shipment_mailer/shipped_email.html.erb +1 -1
- data/config/initializers/assets.rb +1 -1
- data/config/initializers/friendly_id.rb +1 -1
- data/config/locales/en.yml +50 -12
- data/db/default/spree/store_credit.rb +2 -1
- data/db/migrate/20130826062534_add_depth_to_spree_taxons.rb +4 -6
- data/db/migrate/20160420044191_create_spree_wallet_payment_sources.rb +23 -0
- data/db/migrate/20160420181916_migrate_credit_cards_to_wallet_payment_sources.rb +26 -0
- data/db/migrate/20161017102621_create_spree_promotion_code_batch.rb +36 -0
- data/db/migrate/20161129035810_add_index_to_spree_payments_number.rb +5 -0
- data/db/migrate/20170223235001_remove_spree_store_credits_column.rb +5 -0
- data/lib/generators/spree/dummy/templates/rails/application.rb +1 -1
- data/lib/generators/spree/dummy/templates/rails/test.rb +1 -1
- data/lib/generators/spree/install/install_generator.rb +6 -5
- data/lib/spree/core/controller_helpers/payment_parameters.rb +54 -0
- data/lib/spree/core/engine.rb +6 -9
- data/lib/spree/core/version.rb +1 -1
- data/lib/spree/core.rb +0 -1
- data/lib/spree/money.rb +18 -0
- data/lib/spree/permission_sets/default_customer.rb +1 -1
- data/lib/spree/permitted_attributes.rb +1 -1
- data/lib/spree/testing_support/authorization_helpers.rb +1 -0
- data/lib/spree/testing_support/capybara_ext.rb +13 -0
- data/lib/spree/testing_support/factories/order_factory.rb +5 -1
- data/lib/spree/testing_support/factories/payment_factory.rb +1 -1
- data/lib/spree/testing_support/factories/shipment_factory.rb +0 -1
- data/solidus_core.gemspec +3 -3
- data/spec/jobs/promotion_code_batch_job_spec.rb +65 -0
- data/spec/lib/calculated_adjustments_spec.rb +105 -1
- data/spec/lib/spree/core/testing_support/factories/order_factory_spec.rb +4 -1
- data/spec/lib/spree/core/testing_support/factories/payment_factory_spec.rb +8 -0
- data/spec/lib/spree/money_spec.rb +32 -0
- data/spec/lib/spree/permission_sets/default_customer_spec.rb +20 -0
- data/spec/mailers/promotion_code_batch_mailer_spec.rb +45 -0
- data/spec/models/spree/credit_card_spec.rb +86 -86
- data/spec/models/spree/gateway_spec.rb +3 -1
- data/spec/models/spree/inventory_unit_spec.rb +12 -4
- data/spec/models/spree/order/checkout_spec.rb +11 -32
- data/spec/models/spree/order/tax_spec.rb +2 -2
- data/spec/models/spree/order_contents_spec.rb +24 -1
- data/spec/models/spree/order_inventory_spec.rb +130 -83
- data/spec/models/spree/order_spec.rb +15 -117
- data/spec/models/spree/order_update_attributes_spec.rb +1 -44
- data/spec/models/spree/order_updater_spec.rb +10 -13
- data/spec/models/spree/payment_create_spec.rb +5 -1
- data/spec/models/spree/payment_method_spec.rb +16 -0
- data/spec/models/spree/payment_spec.rb +14 -8
- data/spec/models/spree/promotion_code/batch_builder_spec.rb +61 -0
- data/spec/models/spree/promotion_code_batch_spec.rb +58 -0
- data/spec/models/spree/promotion_code_spec.rb +4 -0
- data/spec/models/spree/promotion_spec.rb +3 -6
- data/spec/models/spree/return_authorization_spec.rb +0 -59
- data/spec/models/spree/shipment_spec.rb +4 -4
- data/spec/models/spree/stock/availability_validator_spec.rb +64 -9
- data/spec/models/spree/tax/item_adjuster_spec.rb +1 -2
- data/spec/models/spree/unit_cancel_spec.rb +0 -85
- data/spec/models/spree/user_spec.rb +3 -1
- data/spec/models/spree/variant/vat_price_generator_spec.rb +8 -2
- data/spec/models/spree/variant_spec.rb +16 -4
- data/spec/models/spree/wallet_payment_source_spec.rb +46 -0
- data/spec/models/spree/wallet_spec.rb +128 -0
- data/spec/support/concerns/payment_source.rb +64 -0
- metadata +51 -25
- data/app/assets/javascripts/spree.js.coffee.erb +0 -64
- data/app/models/spree/promotion_builder.rb +0 -55
- data/app/models/spree/promotion_code/code_builder.rb +0 -62
- data/config/initializers/premailer_assets.rb +0 -1
- data/lib/spree/core/unreturned_item_charger.rb +0 -106
- data/lib/tasks/exchanges.rake +0 -47
- data/spec/lib/spree/core/unreturned_item_charger_spec.rb +0 -126
- data/spec/lib/tasks/exchanges_spec.rb +0 -220
- data/spec/models/spree/promotion_builder_spec.rb +0 -120
- data/spec/models/spree/promotion_code/code_builder_spec.rb +0 -77
@@ -67,6 +67,22 @@ describe Spree::PaymentMethod, type: :model do
|
|
67
67
|
|
68
68
|
it { is_expected.to contain_exactly(payment_method_back_display, payment_method_both_display, payment_method_nil_display)}
|
69
69
|
end
|
70
|
+
|
71
|
+
context "when searching for payment methods available to a store" do
|
72
|
+
subject { Spree::PaymentMethod.available_to_store(store) }
|
73
|
+
|
74
|
+
context "when the store is nil" do
|
75
|
+
let(:store) { nil }
|
76
|
+
it "raises an argument error" do
|
77
|
+
expect { subject }.to raise_error(ArgumentError, "You must provide a store")
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
context "when the store exists" do
|
82
|
+
let(:store) { create(:store, payment_methods: [payment_method_back_display]) }
|
83
|
+
it { is_expected.to contain_exactly(payment_method_back_display) }
|
84
|
+
end
|
85
|
+
end
|
70
86
|
end
|
71
87
|
|
72
88
|
describe ".available" do
|
@@ -653,13 +653,12 @@ describe Spree::Payment, type: :model do
|
|
653
653
|
end
|
654
654
|
|
655
655
|
context "completed orders" do
|
656
|
-
let(:payment_method) { create(:check_payment_method) }
|
657
656
|
before { allow(order).to receive_messages completed?: true }
|
658
657
|
|
659
658
|
it "updates payment_state and shipments" do
|
660
659
|
expect(order.updater).to receive(:update_payment_state)
|
661
660
|
expect(order.updater).to receive(:update_shipment_state)
|
662
|
-
Spree::Payment.create
|
661
|
+
Spree::Payment.create(amount: 100, order: order)
|
663
662
|
end
|
664
663
|
end
|
665
664
|
|
@@ -743,13 +742,12 @@ describe Spree::Payment, type: :model do
|
|
743
742
|
end
|
744
743
|
|
745
744
|
describe "invalidating payments updates in memory objects" do
|
746
|
-
let(:payment_method) { create(:check_payment_method) }
|
747
745
|
before do
|
748
|
-
Spree::PaymentCreate.new(order, amount: 1
|
746
|
+
Spree::PaymentCreate.new(order, amount: 1).build.save!
|
749
747
|
expect(order.payments.map(&:state)).to contain_exactly(
|
750
748
|
'checkout'
|
751
749
|
)
|
752
|
-
Spree::PaymentCreate.new(order, amount: 2
|
750
|
+
Spree::PaymentCreate.new(order, amount: 2).build.save!
|
753
751
|
end
|
754
752
|
|
755
753
|
it 'should not have stale payments' do
|
@@ -808,11 +806,12 @@ describe Spree::Payment, type: :model do
|
|
808
806
|
let(:order) { create(:order, user: user) }
|
809
807
|
let(:user) { create(:user) }
|
810
808
|
let!(:credit_card) { create(:credit_card, user_id: order.user_id) }
|
809
|
+
let!(:wallet_payment_source) { user.wallet.add(credit_card) }
|
811
810
|
|
812
811
|
let(:params) do
|
813
812
|
{
|
814
813
|
source_attributes: {
|
815
|
-
|
814
|
+
wallet_payment_source_id: wallet_payment_source.id,
|
816
815
|
verification_value: '321'
|
817
816
|
}
|
818
817
|
}
|
@@ -849,14 +848,21 @@ describe Spree::Payment, type: :model do
|
|
849
848
|
|
850
849
|
context 'the credit card belongs to a different user' do
|
851
850
|
let(:other_user) { create(:user) }
|
852
|
-
before
|
851
|
+
before do
|
852
|
+
credit_card.update!(user_id: other_user.id)
|
853
|
+
user.wallet.remove(credit_card)
|
854
|
+
other_user.wallet.add(credit_card)
|
855
|
+
end
|
853
856
|
it 'errors' do
|
854
857
|
expect { subject }.to raise_error(ActiveRecord::RecordNotFound)
|
855
858
|
end
|
856
859
|
end
|
857
860
|
|
858
861
|
context 'the credit card has no user' do
|
859
|
-
before
|
862
|
+
before do
|
863
|
+
credit_card.update!(user_id: nil)
|
864
|
+
user.wallet.remove(credit_card)
|
865
|
+
end
|
860
866
|
it 'errors' do
|
861
867
|
expect { subject }.to raise_error(ActiveRecord::RecordNotFound)
|
862
868
|
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Spree::PromotionCode::BatchBuilder do
|
4
|
+
let(:promotion) { create(:promotion) }
|
5
|
+
let(:base_code) { "abc" }
|
6
|
+
let(:promotion_code_batch) do
|
7
|
+
Spree::PromotionCodeBatch.create!(
|
8
|
+
promotion_id: promotion.id,
|
9
|
+
base_code: base_code,
|
10
|
+
number_of_codes: 10,
|
11
|
+
email: "test@email.com"
|
12
|
+
)
|
13
|
+
end
|
14
|
+
|
15
|
+
subject { described_class.new promotion_code_batch }
|
16
|
+
|
17
|
+
describe "#build_promotion_codes" do
|
18
|
+
context "with a failed build" do
|
19
|
+
before do
|
20
|
+
allow(subject).to receive(:generate_random_codes).and_raise "Error"
|
21
|
+
|
22
|
+
expect { subject.build_promotion_codes }.to raise_error RuntimeError
|
23
|
+
end
|
24
|
+
|
25
|
+
it "updates the error and state on promotion batch" do
|
26
|
+
expect(promotion_code_batch.reload.error).to eq("#<RuntimeError: Error>")
|
27
|
+
expect(promotion_code_batch.reload.state).to eq("failed")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
context "with a successful build" do
|
31
|
+
before do
|
32
|
+
allow(Spree::PromotionCodeBatchMailer)
|
33
|
+
.to receive(:promotion_code_batch_finished)
|
34
|
+
.and_call_original
|
35
|
+
|
36
|
+
subject.build_promotion_codes
|
37
|
+
end
|
38
|
+
|
39
|
+
it "update the promotion codes count for the batch" do
|
40
|
+
expect(promotion_code_batch.promotion_codes.count).to eq(10)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "builds the correct number of codes" do
|
44
|
+
expect(subject.promotion.codes.size).to eq(10)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "builds codes with distinct values" do
|
48
|
+
expect(subject.promotion.codes.map(&:value).uniq.size).to eq(10)
|
49
|
+
end
|
50
|
+
|
51
|
+
it "builds codes with the same base prefix" do
|
52
|
+
values = subject.promotion.codes.map(&:value)
|
53
|
+
expect(values.all? { |val| val.starts_with?("#{base_code}_") }).to be true
|
54
|
+
end
|
55
|
+
|
56
|
+
it "updates the promotion code batch state to completed" do
|
57
|
+
expect(promotion_code_batch.state).to eq("completed")
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Spree::PromotionCodeBatch, type: :model do
|
4
|
+
include ActiveJob::TestHelper
|
5
|
+
|
6
|
+
subject do
|
7
|
+
described_class.create!(
|
8
|
+
promotion_id: create(:promotion).id,
|
9
|
+
base_code: "abc",
|
10
|
+
number_of_codes: 1,
|
11
|
+
error: nil,
|
12
|
+
email: "test@email.com"
|
13
|
+
)
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "#process" do
|
17
|
+
context "with a pending code batch" do
|
18
|
+
it "should call the worker" do
|
19
|
+
ActiveJob::Base.queue_adapter = :test
|
20
|
+
|
21
|
+
expect { subject.process }
|
22
|
+
.to have_enqueued_job(Spree::PromotionCodeBatchJob)
|
23
|
+
|
24
|
+
clear_enqueued_jobs
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should update the state to processing" do
|
28
|
+
subject.process
|
29
|
+
|
30
|
+
expect(subject.state).to eq("processing")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context "with a processing batch" do
|
35
|
+
before { subject.update_attribute(:state, "processing") }
|
36
|
+
|
37
|
+
it "should raise an error" do
|
38
|
+
expect{ subject.process }.to raise_error Spree::PromotionCodeBatch::CantProcessStartedBatch
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context "with a completed batch" do
|
43
|
+
before { subject.update_attribute(:state, "completed") }
|
44
|
+
|
45
|
+
it "should raise an error" do
|
46
|
+
expect{ subject.process }.to raise_error Spree::PromotionCodeBatch::CantProcessStartedBatch
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context "with a failed batch" do
|
51
|
+
before { subject.update_attribute(:state, "failed") }
|
52
|
+
|
53
|
+
it "should raise an error" do
|
54
|
+
expect{ subject.process }.to raise_error Spree::PromotionCodeBatch::CantProcessStartedBatch
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -164,21 +164,25 @@ RSpec.describe Spree::PromotionCode do
|
|
164
164
|
order.complete!
|
165
165
|
end
|
166
166
|
end
|
167
|
+
|
167
168
|
it "makes the promotion ineligible" do
|
168
169
|
expect{
|
169
170
|
order.complete
|
170
171
|
}.to change{ promo_adjustment.reload.eligible }.to(false)
|
171
172
|
end
|
173
|
+
|
172
174
|
it "adjusts the promo_total" do
|
173
175
|
expect{
|
174
176
|
order.complete
|
175
177
|
}.to change(order, :promo_total).by(10)
|
176
178
|
end
|
179
|
+
|
177
180
|
it "increases the total to remove the promo" do
|
178
181
|
expect{
|
179
182
|
order.complete
|
180
183
|
}.to change(order, :total).from(30).to(40)
|
181
184
|
end
|
185
|
+
|
182
186
|
it "resets the state of the order" do
|
183
187
|
expect{
|
184
188
|
order.complete
|
@@ -597,8 +597,7 @@ describe Spree::Promotion, type: :model do
|
|
597
597
|
allow(rule2).to receive_messages(eligible?: true, applicable?: true)
|
598
598
|
|
599
599
|
promotion.promotion_rules = [rule1, rule2]
|
600
|
-
allow(promotion).to
|
601
|
-
allow(promotion).to receive_message_chain(:rules, :for).and_return(promotion.promotion_rules)
|
600
|
+
allow(promotion.promotion_rules).to receive(:for).and_return(promotion.promotion_rules)
|
602
601
|
end
|
603
602
|
it "returns the eligible rules" do
|
604
603
|
expect(promotion.eligible_rules(promotable)).to eq [rule1, rule2]
|
@@ -616,8 +615,7 @@ describe Spree::Promotion, type: :model do
|
|
616
615
|
allow(rule2).to receive_messages(eligible?: false, applicable?: true, eligibility_errors: errors)
|
617
616
|
|
618
617
|
promotion.promotion_rules = [rule1, rule2]
|
619
|
-
allow(promotion).to
|
620
|
-
allow(promotion).to receive_message_chain(:rules, :for).and_return(promotion.promotion_rules)
|
618
|
+
allow(promotion.promotion_rules).to receive(:for).and_return(promotion.promotion_rules)
|
621
619
|
end
|
622
620
|
it "returns nil" do
|
623
621
|
expect(promotion.eligible_rules(promotable)).to be_nil
|
@@ -649,8 +647,7 @@ describe Spree::Promotion, type: :model do
|
|
649
647
|
allow(rule).to receive_messages(eligible?: false, applicable?: true, eligibility_errors: errors)
|
650
648
|
|
651
649
|
promotion.promotion_rules = [rule]
|
652
|
-
allow(promotion).to
|
653
|
-
allow(promotion).to receive_message_chain(:rules, :none?).and_return(false)
|
650
|
+
allow(promotion.promotion_rules).to receive(:for).and_return(promotion.promotion_rules)
|
654
651
|
end
|
655
652
|
it "returns nil" do
|
656
653
|
expect(promotion.eligible_rules(promotable)).to be_nil
|
@@ -44,65 +44,6 @@ describe Spree::ReturnAuthorization, type: :model do
|
|
44
44
|
expect(return_authorization.errors['base'].size).to eq 0
|
45
45
|
end
|
46
46
|
end
|
47
|
-
|
48
|
-
context "expedited exchanges are configured" do
|
49
|
-
let(:order) { create(:shipped_order, line_items_count: 2) }
|
50
|
-
let(:exchange_return_item) { build(:exchange_return_item, inventory_unit: order.inventory_units.first) }
|
51
|
-
let(:return_item) { build(:return_item, inventory_unit: order.inventory_units.last) }
|
52
|
-
subject { create(:return_authorization, order: order, return_items: [exchange_return_item, return_item]) }
|
53
|
-
|
54
|
-
before do
|
55
|
-
Spree::Config[:expedited_exchanges] = true
|
56
|
-
@pre_exchange_hooks = subject.class.pre_expedited_exchange_hooks
|
57
|
-
end
|
58
|
-
|
59
|
-
after do
|
60
|
-
subject.class.pre_expedited_exchange_hooks = @pre_exchange_hooks
|
61
|
-
end
|
62
|
-
|
63
|
-
context "no items to exchange" do
|
64
|
-
subject { create(:return_authorization, order: order) }
|
65
|
-
|
66
|
-
it "does not create a reimbursement" do
|
67
|
-
expect{ subject.save }.to_not change { Spree::Reimbursement.count }
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
context "items to exchange" do
|
72
|
-
it "calls pre_expedited_exchange hooks with the return items to exchange" do
|
73
|
-
hook = double(:as_null_object)
|
74
|
-
expect(hook).to receive(:call).with [exchange_return_item]
|
75
|
-
subject.class.pre_expedited_exchange_hooks = [hook]
|
76
|
-
subject.save
|
77
|
-
end
|
78
|
-
|
79
|
-
it "attempts to accept all return items requiring exchange" do
|
80
|
-
expect(exchange_return_item).to receive :attempt_accept
|
81
|
-
expect(return_item).not_to receive :attempt_accept
|
82
|
-
subject.save
|
83
|
-
end
|
84
|
-
|
85
|
-
it "performs an exchange reimbursement for the exchange return items" do
|
86
|
-
subject.save
|
87
|
-
reimbursement = Spree::Reimbursement.last
|
88
|
-
expect(reimbursement.order).to eq subject.order
|
89
|
-
expect(reimbursement.return_items).to eq [exchange_return_item]
|
90
|
-
expect(exchange_return_item.reload.exchange_shipment).to be_present
|
91
|
-
end
|
92
|
-
|
93
|
-
context "the reimbursement fails" do
|
94
|
-
before do
|
95
|
-
allow_any_instance_of(Spree::Reimbursement).to receive(:save) { false }
|
96
|
-
allow_any_instance_of(Spree::Reimbursement).to receive(:errors) { double(full_messages: "foo") }
|
97
|
-
end
|
98
|
-
|
99
|
-
it "puts errors on the return authorization" do
|
100
|
-
subject.save
|
101
|
-
expect(subject.errors[:base]).to include "foo"
|
102
|
-
end
|
103
|
-
end
|
104
|
-
end
|
105
|
-
end
|
106
47
|
end
|
107
48
|
|
108
49
|
describe ".before_create" do
|
@@ -724,11 +724,10 @@ describe Spree::Shipment, type: :model do
|
|
724
724
|
expect { shipment.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
725
725
|
end
|
726
726
|
|
727
|
-
it "
|
727
|
+
it "can be destroyed when ready" do
|
728
728
|
shipment = create(:shipment, state: "ready")
|
729
|
-
expect(shipment.destroy).to
|
730
|
-
expect
|
731
|
-
expect { shipment.reload }.not_to raise_error
|
729
|
+
expect(shipment.destroy).to be_truthy
|
730
|
+
expect { shipment.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
732
731
|
end
|
733
732
|
|
734
733
|
it "cannot be destroyed when shipped" do
|
@@ -753,6 +752,7 @@ describe Spree::Shipment, type: :model do
|
|
753
752
|
before do
|
754
753
|
stock_item.set_count_on_hand(10)
|
755
754
|
stock_item.update_attributes!(backorderable: false)
|
755
|
+
inventory_unit.update_attributes!(pending: true)
|
756
756
|
end
|
757
757
|
|
758
758
|
subject { shipment.finalize! }
|
@@ -26,6 +26,7 @@ module Spree
|
|
26
26
|
end
|
27
27
|
|
28
28
|
it "doesn't add a validation error" do
|
29
|
+
subject
|
29
30
|
expect(line_item.errors).to be_empty
|
30
31
|
end
|
31
32
|
end
|
@@ -53,28 +54,82 @@ module Spree
|
|
53
54
|
context "line_item is part of a shipment" do
|
54
55
|
let!(:order) { create(:order_with_line_items) }
|
55
56
|
|
56
|
-
context "has stock in
|
57
|
+
context "has stock in one stock location" do
|
57
58
|
let(:line_item) { order.line_items.first }
|
58
59
|
|
59
60
|
before do
|
60
|
-
|
61
|
-
Spree::StockItem.where(variant_id: variant_ids).update_all(count_on_hand: 10, backorderable: false)
|
61
|
+
line_item.variant.stock_items.update_all(count_on_hand: 10, backorderable: false)
|
62
62
|
end
|
63
63
|
|
64
64
|
include_examples "passes validation"
|
65
65
|
end
|
66
66
|
|
67
|
-
context "
|
68
|
-
let(:
|
69
|
-
let(:
|
67
|
+
context "with stock in multiple locations" do
|
68
|
+
let(:line_item) { order.line_items.first }
|
69
|
+
let(:variant) { line_item.variant }
|
70
70
|
let!(:stock_location_1) { create(:stock_location, name: "Test Warehouse", active: false) }
|
71
71
|
|
72
72
|
before do
|
73
|
-
order.
|
74
|
-
order.contents.
|
75
|
-
|
73
|
+
shipment = order.shipments.create(stock_location: stock_location_1)
|
74
|
+
order.contents.add(variant, 1, shipment: shipment)
|
75
|
+
end
|
76
|
+
|
77
|
+
context "but no stock in either location" do
|
78
|
+
before do
|
79
|
+
variant.stock_items.update_all(count_on_hand: 0, backorderable: false)
|
80
|
+
end
|
81
|
+
include_examples "fails validation"
|
82
|
+
end
|
83
|
+
|
84
|
+
context "but no stock in one location" do
|
85
|
+
before do
|
86
|
+
stock_location_1.stock_items.update_all(count_on_hand: 0, backorderable: false)
|
87
|
+
end
|
88
|
+
|
89
|
+
include_examples "fails validation"
|
90
|
+
end
|
91
|
+
|
92
|
+
context "with enough stock only across locations" do
|
93
|
+
before do
|
94
|
+
variant.stock_items.update_all(count_on_hand: 1, backorderable: false)
|
95
|
+
end
|
96
|
+
include_examples "passes validation"
|
97
|
+
end
|
98
|
+
|
99
|
+
context "but inventory units are finalized" do
|
100
|
+
before do
|
101
|
+
order.inventory_units.update_all(pending: false)
|
102
|
+
end
|
103
|
+
|
104
|
+
include_examples "passes validation"
|
76
105
|
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
context "line_item is split across two shipments" do
|
110
|
+
let!(:order) { create(:order_with_line_items) }
|
111
|
+
let(:line_item) { order.line_items.first }
|
112
|
+
let(:variant) { line_item.variant }
|
113
|
+
let(:stock_location) { order.shipments.first.stock_location }
|
114
|
+
|
115
|
+
before do
|
116
|
+
shipment2 = order.shipments.create!(stock_location: order.shipments.first.stock_location)
|
117
|
+
order.contents.add(variant, 1, shipment: shipment2)
|
118
|
+
variant.stock_items.first.update_columns(count_on_hand: count_on_hand, backorderable: false)
|
119
|
+
end
|
120
|
+
|
121
|
+
context "and there is just enough stock" do
|
122
|
+
let(:count_on_hand) { 2 }
|
123
|
+
include_examples "passes validation"
|
124
|
+
end
|
125
|
+
|
126
|
+
context "and there is not enough stock" do
|
127
|
+
let(:count_on_hand) { 1 }
|
128
|
+
include_examples "fails validation"
|
129
|
+
end
|
77
130
|
|
131
|
+
context "and there is no available stock" do
|
132
|
+
let(:count_on_hand) { 0 }
|
78
133
|
include_examples "fails validation"
|
79
134
|
end
|
80
135
|
end
|
@@ -65,13 +65,12 @@ RSpec.describe Spree::Tax::ItemAdjuster do
|
|
65
65
|
|
66
66
|
context 'when there are matching rates for the zone' do
|
67
67
|
context 'and all rates have the same tax category as the item' do
|
68
|
+
let(:item) { build_stubbed :line_item, order: order, tax_category: item_tax_category }
|
68
69
|
let(:item_tax_category) { build_stubbed(:tax_category) }
|
69
70
|
let(:rate_1) { create :tax_rate, tax_category: item_tax_category }
|
70
71
|
let(:rate_2) { create :tax_rate }
|
71
72
|
let(:rates_for_order_zone) { [rate_1, rate_2] }
|
72
73
|
|
73
|
-
before { allow(item).to receive(:tax_category).and_return(item_tax_category) }
|
74
|
-
|
75
74
|
it 'creates an adjustment for every matching rate' do
|
76
75
|
adjuster.adjust!
|
77
76
|
expect(tax_adjustments.length).to eq(1)
|
@@ -55,90 +55,5 @@ describe Spree::UnitCancel do
|
|
55
55
|
expect { subject }.to raise_error RuntimeError, "Adjustable does not match line item"
|
56
56
|
end
|
57
57
|
end
|
58
|
-
|
59
|
-
context "when exchanges are present" do
|
60
|
-
let!(:order) { create(:order, ship_address: create(:address)) }
|
61
|
-
let!(:product) { create(:product, price: 10.00) }
|
62
|
-
let!(:variant) do
|
63
|
-
create(:variant, price: 10, product: product, track_inventory: false)
|
64
|
-
end
|
65
|
-
let!(:shipping_method) { create(:free_shipping_method) }
|
66
|
-
let(:exchange_variant) do
|
67
|
-
create(:variant, product: variant.product, price: 10, track_inventory: false)
|
68
|
-
end
|
69
|
-
|
70
|
-
before do
|
71
|
-
Spree::Config[:expedited_exchanges] = true
|
72
|
-
end
|
73
|
-
|
74
|
-
# This sets up an order with one shipped inventory unit, one unshipped
|
75
|
-
# inventory unit, and one unshipped exchange inventory unit.
|
76
|
-
before do
|
77
|
-
# Complete an order with 1 line item with quantity=2
|
78
|
-
order.contents.add(variant, 2)
|
79
|
-
order.contents.advance
|
80
|
-
create(:payment, order: order, amount: order.total)
|
81
|
-
order.payments.reload
|
82
|
-
order.contents.advance
|
83
|
-
order.complete!
|
84
|
-
order.reload
|
85
|
-
|
86
|
-
# Ship _one_ of the inventory units
|
87
|
-
@shipment = order.shipments.first
|
88
|
-
@shipped_inventory_unit = order.inventory_units[0]
|
89
|
-
@unshipped_inventory_unit = order.inventory_units[1]
|
90
|
-
order.shipping.ship(
|
91
|
-
inventory_units: [@shipped_inventory_unit],
|
92
|
-
stock_location: @shipment.stock_location,
|
93
|
-
address: order.ship_address,
|
94
|
-
shipping_method: @shipment.shipping_method
|
95
|
-
)
|
96
|
-
|
97
|
-
# Create an expedited exchange for the shipped inventory unit.
|
98
|
-
# This generates a new inventory unit attached to the existing line item.
|
99
|
-
Spree::ReturnAuthorization.create!(
|
100
|
-
order: order,
|
101
|
-
stock_location: @shipment.stock_location,
|
102
|
-
reason: create(:return_reason),
|
103
|
-
return_items: [
|
104
|
-
Spree::ReturnItem.new(
|
105
|
-
inventory_unit: @shipped_inventory_unit,
|
106
|
-
exchange_variant: exchange_variant
|
107
|
-
)
|
108
|
-
]
|
109
|
-
)
|
110
|
-
@exchange_inventory_unit = order.inventory_units.reload[2]
|
111
|
-
end
|
112
|
-
|
113
|
-
context 'when canceling an unshipped inventory unit from the original order' do
|
114
|
-
subject do
|
115
|
-
unit_cancel.compute_amount(@unshipped_inventory_unit.line_item)
|
116
|
-
end
|
117
|
-
|
118
|
-
let(:unit_cancel) do
|
119
|
-
Spree::UnitCancel.create!(
|
120
|
-
inventory_unit: @unshipped_inventory_unit,
|
121
|
-
reason: Spree::UnitCancel::SHORT_SHIP
|
122
|
-
)
|
123
|
-
end
|
124
|
-
|
125
|
-
it { is_expected.to eq(-10.00) }
|
126
|
-
end
|
127
|
-
|
128
|
-
context 'when canceling an unshipped exchange inventory unit' do
|
129
|
-
subject do
|
130
|
-
unit_cancel.compute_amount(@exchange_inventory_unit.line_item)
|
131
|
-
end
|
132
|
-
|
133
|
-
let(:unit_cancel) do
|
134
|
-
Spree::UnitCancel.create!(
|
135
|
-
inventory_unit: @exchange_inventory_unit,
|
136
|
-
reason: Spree::UnitCancel::SHORT_SHIP
|
137
|
-
)
|
138
|
-
end
|
139
|
-
|
140
|
-
it { is_expected.to eq(-10.00) }
|
141
|
-
end
|
142
|
-
end
|
143
58
|
end
|
144
59
|
end
|
@@ -92,7 +92,9 @@ describe Spree::LegacyUser, type: :model do
|
|
92
92
|
end
|
93
93
|
|
94
94
|
it "has payment sources" do
|
95
|
-
|
95
|
+
Spree::Deprecation.silence do
|
96
|
+
expect(user.payment_sources.first.gateway_customer_profile_id).not_to be_empty
|
97
|
+
end
|
96
98
|
end
|
97
99
|
end
|
98
100
|
end
|
@@ -30,10 +30,16 @@ describe Spree::Variant::VatPriceGenerator do
|
|
30
30
|
end
|
31
31
|
|
32
32
|
it "will not build prices that are already present" do
|
33
|
-
variant.prices.build(amount: 11, country_iso: "FR")
|
34
|
-
variant.prices.build(amount: 11, country_iso: nil)
|
35
33
|
expect { subject }.not_to change { variant.prices.length }
|
36
34
|
end
|
35
|
+
|
36
|
+
# We need to remove the price for FR from the database so it is created in memory, and then run VatPriceGenerator twice to trigger the duplicate price issue.
|
37
|
+
it "will not build duplicate prices on multiple runs" do
|
38
|
+
variant.prices.where(country_iso: "FR").destroy_all
|
39
|
+
variant.reload
|
40
|
+
described_class.new(variant).run
|
41
|
+
expect { subject }.not_to change { variant.prices.size }
|
42
|
+
end
|
37
43
|
end
|
38
44
|
|
39
45
|
context "with no default admin country" do
|
@@ -66,17 +66,19 @@ describe Spree::Variant, type: :model do
|
|
66
66
|
let!(:high_vat) { create(:tax_rate, included_in_price: true, amount: 0.25, zone: high_vat_zone, tax_category: tax_category) }
|
67
67
|
let!(:low_vat) { create(:tax_rate, included_in_price: true, amount: 0.15, zone: low_vat_zone, tax_category: tax_category) }
|
68
68
|
|
69
|
-
let(:product) {
|
69
|
+
let(:product) { build(:product, tax_category: tax_category) }
|
70
70
|
|
71
|
-
subject(:new_variant) {
|
71
|
+
subject(:new_variant) { build(:variant, price: 15) }
|
72
72
|
|
73
73
|
it "creates the appropriate prices for them" do
|
74
|
-
|
75
|
-
|
74
|
+
product.variants << new_variant
|
75
|
+
product.save!
|
76
76
|
expect(new_variant.prices.find_by(country_iso: "FR").amount).to eq(17.25)
|
77
77
|
expect(new_variant.prices.find_by(country_iso: "DE").amount).to eq(18.75)
|
78
78
|
expect(new_variant.prices.find_by(country_iso: "DK").amount).to eq(18.75)
|
79
79
|
expect(new_variant.prices.find_by(country_iso: nil).amount).to eq(15.00)
|
80
|
+
# default price + FR, DE, DK
|
81
|
+
expect(new_variant.prices.count).to eq(4)
|
80
82
|
end
|
81
83
|
|
82
84
|
context "when the products price changes" do
|
@@ -561,6 +563,16 @@ describe Spree::Variant, type: :model do
|
|
561
563
|
end
|
562
564
|
end
|
563
565
|
end
|
566
|
+
|
567
|
+
describe "cache clearing on update" do
|
568
|
+
it "correctly reports after updating track_inventory" do
|
569
|
+
variant.stock_items.first.set_count_on_hand 0
|
570
|
+
expect(variant).not_to be_in_stock
|
571
|
+
|
572
|
+
variant.update!(track_inventory: false)
|
573
|
+
expect(variant).to be_in_stock
|
574
|
+
end
|
575
|
+
end
|
564
576
|
end
|
565
577
|
|
566
578
|
describe '#is_backorderable' do
|