solidus_core 2.1.1 → 2.2.0.beta1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
describe Spree::PromotionCodeBatchJob, type: :job do
|
|
3
|
+
let(:email) { "test@email.com" }
|
|
4
|
+
let(:promotion_code_batch) do
|
|
5
|
+
Spree::PromotionCodeBatch.create!(
|
|
6
|
+
promotion_id: create(:promotion).id,
|
|
7
|
+
base_code: "test",
|
|
8
|
+
number_of_codes: 10,
|
|
9
|
+
email: email
|
|
10
|
+
)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
context "with a successful build" do
|
|
14
|
+
before do
|
|
15
|
+
allow(Spree::PromotionCodeBatchMailer)
|
|
16
|
+
.to receive(:promotion_code_batch_finished)
|
|
17
|
+
.and_call_original
|
|
18
|
+
end
|
|
19
|
+
context "with an email address" do
|
|
20
|
+
it "sends an email" do
|
|
21
|
+
subject.perform(promotion_code_batch)
|
|
22
|
+
expect(Spree::PromotionCodeBatchMailer)
|
|
23
|
+
.to have_received(:promotion_code_batch_finished)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
context "with no email address" do
|
|
27
|
+
let(:email) { nil }
|
|
28
|
+
it "sends an email" do
|
|
29
|
+
subject.perform(promotion_code_batch)
|
|
30
|
+
expect(Spree::PromotionCodeBatchMailer)
|
|
31
|
+
.to_not have_received(:promotion_code_batch_finished)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
context "with a failed build" do
|
|
37
|
+
before do
|
|
38
|
+
allow_any_instance_of(Spree::PromotionCode::BatchBuilder)
|
|
39
|
+
.to receive(:build_promotion_codes)
|
|
40
|
+
.and_raise("Error")
|
|
41
|
+
|
|
42
|
+
allow(Spree::PromotionCodeBatchMailer)
|
|
43
|
+
.to receive(:promotion_code_batch_errored)
|
|
44
|
+
.and_call_original
|
|
45
|
+
|
|
46
|
+
expect { subject.perform(promotion_code_batch) }
|
|
47
|
+
.to raise_error RuntimeError
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
context "with an email address" do
|
|
51
|
+
it "sends an email" do
|
|
52
|
+
expect(Spree::PromotionCodeBatchMailer)
|
|
53
|
+
.to have_received(:promotion_code_batch_errored)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
context "with no email address" do
|
|
58
|
+
let(:email) { nil }
|
|
59
|
+
it "sends an email" do
|
|
60
|
+
expect(Spree::PromotionCodeBatchMailer)
|
|
61
|
+
.to_not have_received(:promotion_code_batch_errored)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -1,7 +1,111 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
3
|
describe Spree::CalculatedAdjustments do
|
|
4
|
+
let(:calculator_class) { Spree::Calculator::FlatRate }
|
|
5
|
+
|
|
6
|
+
with_model :Calculable, scope: :all do
|
|
7
|
+
model do
|
|
8
|
+
include Spree::CalculatedAdjustments
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
4
12
|
it "should add has_one :calculator relationship" do
|
|
5
|
-
|
|
13
|
+
expect(Calculable.reflect_on_all_associations(:has_one).map(&:name)).to include(:calculator)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
describe 'initialization' do
|
|
17
|
+
context 'with no calculator' do
|
|
18
|
+
subject { Calculable.new }
|
|
19
|
+
|
|
20
|
+
it 'can be initialized' do
|
|
21
|
+
expect(subject.calculator).to be nil
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it 'is not valid' do
|
|
25
|
+
expect(subject).not_to be_valid
|
|
26
|
+
expect(subject.errors[:calculator]).to eq ["can't be blank"]
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
context 'with calculator object' do
|
|
31
|
+
subject { Calculable.new(calculator: calculator_class.new) }
|
|
32
|
+
|
|
33
|
+
it 'can be initialized' do
|
|
34
|
+
expect(subject.calculator).to be_a(calculator_class)
|
|
35
|
+
expect(calculator_class.count).to eq 0 # not yet saved
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it 'can be created' do
|
|
39
|
+
subject.save!
|
|
40
|
+
expect(subject.calculator).to be_a(calculator_class)
|
|
41
|
+
expect(calculator_class.count).to eq 1 # saved in database
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
context 'with calculator_type' do
|
|
46
|
+
subject { Calculable.new(calculator_type: calculator_class.to_s) }
|
|
47
|
+
|
|
48
|
+
it 'can be initialized' do
|
|
49
|
+
expect(subject.calculator).to be_a(calculator_class)
|
|
50
|
+
expect(calculator_class.count).to eq 0 # not yet saved
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
it 'can be created' do
|
|
54
|
+
subject.save!
|
|
55
|
+
expect(subject.calculator).to be_a(calculator_class)
|
|
56
|
+
expect(calculator_class.count).to eq 1 # saved in database
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
context 'with calculator_type and calculator_attributes' do
|
|
61
|
+
subject { Calculable.new(calculator_type: calculator_class.to_s, calculator_attributes: {preferred_amount: 123}) }
|
|
62
|
+
|
|
63
|
+
it 'can be initialized' do
|
|
64
|
+
expect(subject.calculator).to be_a(calculator_class)
|
|
65
|
+
expect(subject.calculator.preferred_amount).to eq 123
|
|
66
|
+
expect(calculator_class.count).to eq 0 # not yet saved
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
it 'can be created' do
|
|
70
|
+
subject.save!
|
|
71
|
+
expect(subject.calculator).to be_a(calculator_class)
|
|
72
|
+
expect(subject.calculator.preferred_amount).to eq 123
|
|
73
|
+
expect(calculator_class.count).to eq 1 # saved in database
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
describe 'update' do
|
|
79
|
+
subject { Calculable.create!(calculator_type: calculator_class.to_s) }
|
|
80
|
+
|
|
81
|
+
it "can update calculator attributes with id" do
|
|
82
|
+
subject.update!(calculator_attributes: {
|
|
83
|
+
id: subject.calculator.id,
|
|
84
|
+
preferred_amount: 123
|
|
85
|
+
})
|
|
86
|
+
expect(subject.calculator.preferred_amount).to eq(123)
|
|
87
|
+
subject.reload
|
|
88
|
+
expect(subject.calculator.preferred_amount).to eq(123)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
it "can update calculator attributes without id" do
|
|
92
|
+
subject.update!(calculator_attributes: {
|
|
93
|
+
preferred_amount: 123
|
|
94
|
+
})
|
|
95
|
+
expect(subject.calculator.preferred_amount).to eq(123)
|
|
96
|
+
subject.reload
|
|
97
|
+
expect(subject.calculator.preferred_amount).to eq(123)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
it "can update both calculator type and attributes" do
|
|
101
|
+
subject.update!(calculator_type: 'Spree::Calculator::FlexiRate', calculator_attributes: {
|
|
102
|
+
preferred_first_item: 123
|
|
103
|
+
})
|
|
104
|
+
expect(subject.calculator.class).to eq(Spree::Calculator::FlexiRate)
|
|
105
|
+
expect(subject.calculator.preferred_first_item).to eq(123)
|
|
106
|
+
subject.reload
|
|
107
|
+
expect(subject.calculator.class).to eq(Spree::Calculator::FlexiRate)
|
|
108
|
+
expect(subject.calculator.preferred_first_item).to eq(123)
|
|
109
|
+
end
|
|
6
110
|
end
|
|
7
111
|
end
|
|
@@ -122,6 +122,8 @@ RSpec.describe 'order factory' do
|
|
|
122
122
|
total: 110,
|
|
123
123
|
state: 'complete'
|
|
124
124
|
)
|
|
125
|
+
expect(order.inventory_units.where(pending: true)).to be_empty
|
|
126
|
+
expect(order.inventory_units.where(pending: false)).to_not be_empty
|
|
125
127
|
end
|
|
126
128
|
end
|
|
127
129
|
end
|
|
@@ -201,7 +203,8 @@ RSpec.describe 'order factory' do
|
|
|
201
203
|
expect(order).to have_attributes(
|
|
202
204
|
total: 110,
|
|
203
205
|
payment_total: 110,
|
|
204
|
-
payment_state: "paid"
|
|
206
|
+
payment_state: "paid",
|
|
207
|
+
shipment_state: "shipped"
|
|
205
208
|
)
|
|
206
209
|
|
|
207
210
|
expect(order.payments.count).to eq 1
|
|
@@ -14,6 +14,14 @@ RSpec.describe 'payment factory' do
|
|
|
14
14
|
expect(payment.source.user).to be_present
|
|
15
15
|
expect(payment.source.user).to eq payment.order.user
|
|
16
16
|
end
|
|
17
|
+
|
|
18
|
+
it 'uses the orders bill address for the credit card' do
|
|
19
|
+
address = create(:address)
|
|
20
|
+
order = create(:order, bill_address: address)
|
|
21
|
+
payment = create(factory, order: order)
|
|
22
|
+
|
|
23
|
+
expect(payment.source.address).to eq address
|
|
24
|
+
end
|
|
17
25
|
end
|
|
18
26
|
|
|
19
27
|
describe 'check payment' do
|
|
@@ -268,4 +268,36 @@ describe Spree::Money do
|
|
|
268
268
|
end
|
|
269
269
|
end
|
|
270
270
|
end
|
|
271
|
+
|
|
272
|
+
it "includes Comparable" do
|
|
273
|
+
expect(described_class).to include(Comparable)
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
describe "<=>" do
|
|
277
|
+
let(:usd_10) { Spree::Money.new(10, currency: "USD") }
|
|
278
|
+
let(:usd_20) { Spree::Money.new(20, currency: "USD") }
|
|
279
|
+
let(:usd_30) { Spree::Money.new(30, currency: "USD") }
|
|
280
|
+
|
|
281
|
+
it "compares the two amounts" do
|
|
282
|
+
expect(usd_20 <=> usd_20).to eq 0
|
|
283
|
+
expect(usd_20 <=> usd_10).to be > 0
|
|
284
|
+
expect(usd_20 <=> usd_30).to be < 0
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
context "with a non Spree::Money object" do
|
|
288
|
+
it "raises an error" do
|
|
289
|
+
expect { usd_10 <=> 20 }.to raise_error(TypeError)
|
|
290
|
+
end
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
context "with differing currencies" do
|
|
294
|
+
let(:cad) { Spree::Money.new(10, currency: "CAD") }
|
|
295
|
+
|
|
296
|
+
it "raises an error" do
|
|
297
|
+
expect { usd_10 <=> cad }.to raise_error(
|
|
298
|
+
Spree::Money::DifferentCurrencyError
|
|
299
|
+
)
|
|
300
|
+
end
|
|
301
|
+
end
|
|
302
|
+
end
|
|
271
303
|
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Spree::PermissionSets::DefaultCustomer do
|
|
4
|
+
context 'as Guest User' do
|
|
5
|
+
context 'for Order' do
|
|
6
|
+
context 'guest_token is empty string' do
|
|
7
|
+
let(:ability) { Spree::Ability.new(nil) }
|
|
8
|
+
let(:resource) { build(:order) }
|
|
9
|
+
let(:token) { '' }
|
|
10
|
+
|
|
11
|
+
it 'should not be allowed to read or update the order' do
|
|
12
|
+
allow(resource).to receive_messages(guest_token: '')
|
|
13
|
+
|
|
14
|
+
expect(ability).to_not be_able_to(:read, resource, token)
|
|
15
|
+
expect(ability).to_not be_able_to(:update, resource, token)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
describe Spree::PromotionCodeBatchMailer, type: :mailer do
|
|
3
|
+
let(:promotion) { create(:promotion, name: "Promotion Test") }
|
|
4
|
+
let(:promotion_code_batch) do
|
|
5
|
+
Spree::PromotionCodeBatch.create!(
|
|
6
|
+
promotion_id: promotion.id,
|
|
7
|
+
base_code: "test",
|
|
8
|
+
number_of_codes: 10,
|
|
9
|
+
email: "test@email.com"
|
|
10
|
+
)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
describe "#promotion_code_batch_finished" do
|
|
14
|
+
subject { described_class.promotion_code_batch_finished(promotion_code_batch) }
|
|
15
|
+
|
|
16
|
+
it "sends the email to the email attached to the promotion code batch " do
|
|
17
|
+
expect(subject.to).to eq([promotion_code_batch.email])
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it "contains the number of codes created" do
|
|
21
|
+
expect(subject.body).to include("All 10 codes have been created")
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "contains the name of the promotion" do
|
|
25
|
+
expect(subject.body).to include(promotion.name)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
describe "#promotion_code_batch_errored" do
|
|
30
|
+
before { promotion_code_batch.update(error: "Test error") }
|
|
31
|
+
subject { described_class.promotion_code_batch_errored(promotion_code_batch) }
|
|
32
|
+
|
|
33
|
+
it "sends the email to the email attached to the promotion code batch " do
|
|
34
|
+
expect(subject.to).to eq([promotion_code_batch.email])
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it "contains the error" do
|
|
38
|
+
expect(subject.body).to include("Test error")
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "contains the name of the promotion" do
|
|
42
|
+
expect(subject.body).to include(promotion.name)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -16,6 +16,8 @@ describe Spree::CreditCard, type: :model do
|
|
|
16
16
|
|
|
17
17
|
let(:credit_card) { Spree::CreditCard.new }
|
|
18
18
|
|
|
19
|
+
it_behaves_like 'a payment source'
|
|
20
|
+
|
|
19
21
|
before(:each) do
|
|
20
22
|
@order = create(:order)
|
|
21
23
|
@payment = Spree::Payment.create(amount: 100, order: @order)
|
|
@@ -35,37 +37,6 @@ describe Spree::CreditCard, type: :model do
|
|
|
35
37
|
allow(@payment).to receive_messages payment_method: @payment_gateway
|
|
36
38
|
end
|
|
37
39
|
|
|
38
|
-
describe "#can_capture?" do
|
|
39
|
-
it "should be true if payment is pending" do
|
|
40
|
-
payment = mock_model(Spree::Payment, pending?: true, created_at: Time.current)
|
|
41
|
-
expect(credit_card.can_capture?(payment)).to be true
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
it "should be true if payment is checkout" do
|
|
45
|
-
payment = mock_model(Spree::Payment, pending?: false, checkout?: true, created_at: Time.current)
|
|
46
|
-
expect(credit_card.can_capture?(payment)).to be true
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
describe "#can_void?" do
|
|
51
|
-
it "should be true if payment is not void" do
|
|
52
|
-
payment = mock_model(Spree::Payment, failed?: false, void?: false)
|
|
53
|
-
expect(credit_card.can_void?(payment)).to be true
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
describe "#can_credit?" do
|
|
58
|
-
it "should be false if payment is not completed" do
|
|
59
|
-
payment = mock_model(Spree::Payment, completed?: false)
|
|
60
|
-
expect(credit_card.can_credit?(payment)).to be false
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
it "should be false when credit_allowed is zero" do
|
|
64
|
-
payment = mock_model(Spree::Payment, completed?: true, credit_allowed: 0, order: mock_model(Spree::Order, payment_state: 'credit_owed'))
|
|
65
|
-
expect(credit_card.can_credit?(payment)).to be false
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
|
|
69
40
|
describe "#valid?" do
|
|
70
41
|
it "should validate presence of number" do
|
|
71
42
|
credit_card.attributes = valid_credit_card_attributes.except(:number)
|
|
@@ -283,32 +254,6 @@ describe Spree::CreditCard, type: :model do
|
|
|
283
254
|
end
|
|
284
255
|
end
|
|
285
256
|
|
|
286
|
-
describe "#associations" do
|
|
287
|
-
it "should be able to access its payments" do
|
|
288
|
-
credit_card.payments.to_a
|
|
289
|
-
end
|
|
290
|
-
end
|
|
291
|
-
|
|
292
|
-
describe "#first_name" do
|
|
293
|
-
before do
|
|
294
|
-
credit_card.name = "Ludwig van Beethoven"
|
|
295
|
-
end
|
|
296
|
-
|
|
297
|
-
it "extracts the first name" do
|
|
298
|
-
expect(credit_card.first_name).to eq "Ludwig"
|
|
299
|
-
end
|
|
300
|
-
end
|
|
301
|
-
|
|
302
|
-
describe "#last_name" do
|
|
303
|
-
before do
|
|
304
|
-
credit_card.name = "Ludwig van Beethoven"
|
|
305
|
-
end
|
|
306
|
-
|
|
307
|
-
it "extracts the last name" do
|
|
308
|
-
expect(credit_card.last_name).to eq "van Beethoven"
|
|
309
|
-
end
|
|
310
|
-
end
|
|
311
|
-
|
|
312
257
|
describe "#to_active_merchant" do
|
|
313
258
|
before do
|
|
314
259
|
credit_card.number = "4111111111111111"
|
|
@@ -329,44 +274,99 @@ describe Spree::CreditCard, type: :model do
|
|
|
329
274
|
end
|
|
330
275
|
end
|
|
331
276
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
277
|
+
# TODO: Remove these specs once default is removed
|
|
278
|
+
describe 'default' do
|
|
279
|
+
def default_with_silence(card)
|
|
280
|
+
Spree::Deprecation.silence { card.default }
|
|
281
|
+
end
|
|
336
282
|
|
|
337
|
-
|
|
338
|
-
|
|
283
|
+
context 'with a user' do
|
|
284
|
+
let(:user) { create(:user) }
|
|
285
|
+
let(:credit_card) { create(:credit_card, user: user) }
|
|
339
286
|
|
|
340
|
-
|
|
341
|
-
|
|
287
|
+
it 'uses the wallet information' do
|
|
288
|
+
wallet_payment_source = user.wallet.add(credit_card)
|
|
289
|
+
user.wallet.default_wallet_payment_source = wallet_payment_source
|
|
342
290
|
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
291
|
+
expect(default_with_silence(credit_card)).to be_truthy
|
|
292
|
+
end
|
|
293
|
+
end
|
|
346
294
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
second = FactoryGirl.create(:credit_card, user: FactoryGirl.create(:user), default: true)
|
|
295
|
+
context 'without a user' do
|
|
296
|
+
let(:credit_card) { create(:credit_card) }
|
|
350
297
|
|
|
351
|
-
|
|
352
|
-
|
|
298
|
+
it 'returns false' do
|
|
299
|
+
expect(default_with_silence(credit_card)).to eq(false)
|
|
300
|
+
end
|
|
301
|
+
end
|
|
353
302
|
end
|
|
354
303
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
304
|
+
# TODO: Remove these specs once default= is removed
|
|
305
|
+
describe 'default=' do
|
|
306
|
+
def default_with_silence(card)
|
|
307
|
+
Spree::Deprecation.silence { card.default }
|
|
308
|
+
end
|
|
360
309
|
|
|
361
|
-
|
|
362
|
-
|
|
310
|
+
context 'with a user' do
|
|
311
|
+
let(:user) { create(:user) }
|
|
312
|
+
let(:credit_card) { create(:credit_card, user: user) }
|
|
313
|
+
|
|
314
|
+
it 'updates the wallet information' do
|
|
315
|
+
Spree::Deprecation.silence do
|
|
316
|
+
credit_card.default = true
|
|
317
|
+
end
|
|
318
|
+
expect(user.wallet.default_wallet_payment_source.payment_source).to eq(credit_card)
|
|
319
|
+
end
|
|
320
|
+
end
|
|
363
321
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
first.update_columns(year: DateTime.current.year, month: 1.month.ago.month)
|
|
322
|
+
context 'with multiple cards for one user' do
|
|
323
|
+
let(:user) { create(:user) }
|
|
324
|
+
let(:first_card) { create(:credit_card, user: user) }
|
|
325
|
+
let(:second_card) { create(:credit_card, user: user) }
|
|
369
326
|
|
|
370
|
-
|
|
327
|
+
it 'ensures only one default' do
|
|
328
|
+
Spree::Deprecation.silence do
|
|
329
|
+
first_card.default = true
|
|
330
|
+
second_card.default = true
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
expect(default_with_silence(first_card)).to be_falsey
|
|
334
|
+
expect(default_with_silence(second_card)).to be_truthy
|
|
335
|
+
|
|
336
|
+
Spree::Deprecation.silence do
|
|
337
|
+
first_card.default = true
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
expect(default_with_silence(first_card)).to be_truthy
|
|
341
|
+
expect(default_with_silence(second_card)).to be_falsey
|
|
342
|
+
end
|
|
343
|
+
end
|
|
344
|
+
|
|
345
|
+
context 'with multiple cards for different users' do
|
|
346
|
+
let(:first_card) { create(:credit_card, user: create(:user)) }
|
|
347
|
+
let(:second_card) { create(:credit_card, user: create(:user)) }
|
|
348
|
+
|
|
349
|
+
it 'allows multiple defaults' do
|
|
350
|
+
Spree::Deprecation.silence do
|
|
351
|
+
first_card.default = true
|
|
352
|
+
second_card.default = true
|
|
353
|
+
end
|
|
354
|
+
|
|
355
|
+
expect(default_with_silence(first_card)).to be_truthy
|
|
356
|
+
expect(default_with_silence(second_card)).to be_truthy
|
|
357
|
+
end
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
context 'without a user' do
|
|
361
|
+
let(:credit_card) { create(:credit_card) }
|
|
362
|
+
|
|
363
|
+
it 'raises' do
|
|
364
|
+
expect {
|
|
365
|
+
Spree::Deprecation.silence do
|
|
366
|
+
credit_card.default = true
|
|
367
|
+
end
|
|
368
|
+
}.to raise_error("Cannot set 'default' on a credit card without a user")
|
|
369
|
+
end
|
|
370
|
+
end
|
|
371
371
|
end
|
|
372
372
|
end
|
|
@@ -85,7 +85,9 @@ describe Spree::Gateway, type: :model do
|
|
|
85
85
|
context 'order is not complete but credit card has user' do
|
|
86
86
|
let(:cc_user) { user }
|
|
87
87
|
let(:completed_at) { nil }
|
|
88
|
-
|
|
88
|
+
before do
|
|
89
|
+
cc_user.wallet.add(cc)
|
|
90
|
+
end
|
|
89
91
|
it "finds credit cards associated to the user" do
|
|
90
92
|
expect(payment_method.reusable_sources(payment.order)).to eq [cc]
|
|
91
93
|
end
|
|
@@ -5,6 +5,15 @@ describe Spree::InventoryUnit, type: :model do
|
|
|
5
5
|
let(:stock_item) { stock_location.stock_items.order(:id).first }
|
|
6
6
|
let(:line_item) { create(:line_item, variant: stock_item.variant) }
|
|
7
7
|
|
|
8
|
+
describe ".cancelable" do
|
|
9
|
+
let!(:pending_unit) { create(:inventory_unit, pending: true) }
|
|
10
|
+
let!(:non_pending_unit) { create(:inventory_unit, pending: false) }
|
|
11
|
+
|
|
12
|
+
subject { described_class.cancelable }
|
|
13
|
+
|
|
14
|
+
it { is_expected.to contain_exactly(non_pending_unit) }
|
|
15
|
+
end
|
|
16
|
+
|
|
8
17
|
context "#backordered_for_stock_item" do
|
|
9
18
|
let(:order) do
|
|
10
19
|
order = create(:order, state: 'complete', ship_address: create(:ship_address))
|
|
@@ -289,11 +298,10 @@ describe Spree::InventoryUnit, type: :model do
|
|
|
289
298
|
expect { inventory_unit.reload }.not_to raise_error
|
|
290
299
|
end
|
|
291
300
|
|
|
292
|
-
it "
|
|
301
|
+
it "can be destroyed if its shipment is ready" do
|
|
293
302
|
inventory_unit = create(:order_ready_to_ship).inventory_units.first
|
|
294
|
-
expect(inventory_unit.destroy).to
|
|
295
|
-
expect
|
|
296
|
-
expect { inventory_unit.reload }.not_to raise_error
|
|
303
|
+
expect(inventory_unit.destroy).to be_truthy
|
|
304
|
+
expect { inventory_unit.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
|
297
305
|
end
|
|
298
306
|
|
|
299
307
|
it "cannot be destroyed if its shipment is shipped" do
|
|
@@ -254,11 +254,6 @@ describe Spree::Order, type: :model do
|
|
|
254
254
|
allow(order).to receive(:ensure_available_shipping_rates) { true }
|
|
255
255
|
end
|
|
256
256
|
|
|
257
|
-
it 'should invoke set_shipment_cost' do
|
|
258
|
-
expect(order).to receive(:set_shipments_cost)
|
|
259
|
-
order.next!
|
|
260
|
-
end
|
|
261
|
-
|
|
262
257
|
it 'should update shipment_total' do
|
|
263
258
|
expect { order.next! }.to change{ order.shipment_total }.by(10.00)
|
|
264
259
|
end
|
|
@@ -300,7 +295,6 @@ describe Spree::Order, type: :model do
|
|
|
300
295
|
end
|
|
301
296
|
|
|
302
297
|
it "transitions to payment" do
|
|
303
|
-
expect(order).to receive(:set_shipments_cost)
|
|
304
298
|
order.next!
|
|
305
299
|
assert_state_changed(order, 'delivery', 'payment')
|
|
306
300
|
expect(order.state).to eq('payment')
|
|
@@ -333,7 +327,7 @@ describe Spree::Order, type: :model do
|
|
|
333
327
|
context "with a shipment that has a price" do
|
|
334
328
|
before do
|
|
335
329
|
shipment.shipping_rates.first.update_column(:cost, 10)
|
|
336
|
-
order.
|
|
330
|
+
order.update!
|
|
337
331
|
end
|
|
338
332
|
|
|
339
333
|
it "transitions to payment" do
|
|
@@ -345,7 +339,6 @@ describe Spree::Order, type: :model do
|
|
|
345
339
|
context "with a shipment that is free" do
|
|
346
340
|
before do
|
|
347
341
|
shipment.shipping_rates.first.update_column(:cost, 0)
|
|
348
|
-
order.set_shipments_cost
|
|
349
342
|
end
|
|
350
343
|
|
|
351
344
|
it "skips payment, transitions to confirm" do
|
|
@@ -362,8 +355,9 @@ describe Spree::Order, type: :model do
|
|
|
362
355
|
let(:default_credit_card) { create(:credit_card) }
|
|
363
356
|
|
|
364
357
|
before do
|
|
365
|
-
user =
|
|
366
|
-
|
|
358
|
+
user = create(:user, email: 'spree@example.org', bill_address: user_bill_address)
|
|
359
|
+
wallet_payment_source = user.wallet.add(default_credit_card)
|
|
360
|
+
user.wallet.default_wallet_payment_source = wallet_payment_source
|
|
367
361
|
order.user = user
|
|
368
362
|
|
|
369
363
|
allow(order).to receive_messages(payment_required?: true)
|
|
@@ -533,24 +527,9 @@ describe Spree::Order, type: :model do
|
|
|
533
527
|
order.save!
|
|
534
528
|
end
|
|
535
529
|
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
expect(order.unreturned_exchange?).to eq true
|
|
540
|
-
end
|
|
541
|
-
|
|
542
|
-
it 'allows the order to complete' do
|
|
543
|
-
order.complete!
|
|
544
|
-
|
|
545
|
-
expect(order).to be_complete
|
|
546
|
-
end
|
|
547
|
-
end
|
|
548
|
-
|
|
549
|
-
context 'when the exchange is not for an unreturned item' do
|
|
550
|
-
it 'does not allow the order to completed' do
|
|
551
|
-
expect { order.complete! }.to raise_error Spree::Order::InsufficientStock
|
|
552
|
-
expect(order.payments.first.state).to eq('checkout')
|
|
553
|
-
end
|
|
530
|
+
it 'does not allow the order to completed' do
|
|
531
|
+
expect { order.complete! }.to raise_error Spree::Order::InsufficientStock
|
|
532
|
+
expect(order.payments.first.state).to eq('checkout')
|
|
554
533
|
end
|
|
555
534
|
end
|
|
556
535
|
end
|
|
@@ -576,13 +555,13 @@ describe Spree::Order, type: :model do
|
|
|
576
555
|
it "makes the current credit card a user's default credit card" do
|
|
577
556
|
order.complete!
|
|
578
557
|
expect(order.state).to eq 'complete'
|
|
579
|
-
expect(order.user.reload.
|
|
558
|
+
expect(order.user.reload.wallet.default_wallet_payment_source.payment_source).to eq(order.credit_cards.first)
|
|
580
559
|
end
|
|
581
560
|
|
|
582
|
-
it "does not assign a default credit card if
|
|
583
|
-
order.
|
|
561
|
+
it "does not assign a default credit card if temporary_payment_source is set" do
|
|
562
|
+
order.temporary_payment_source = true
|
|
584
563
|
order.complete!
|
|
585
|
-
expect(order.user.reload.
|
|
564
|
+
expect(order.user.reload.wallet.default_wallet_payment_source).to be_nil
|
|
586
565
|
end
|
|
587
566
|
end
|
|
588
567
|
|
|
@@ -18,7 +18,7 @@ module Spree
|
|
|
18
18
|
end
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
-
context "when :
|
|
21
|
+
context "when tax_using_ship_address: true" do
|
|
22
22
|
before { Spree::Config.set(tax_using_ship_address: true) }
|
|
23
23
|
|
|
24
24
|
it "should calculate using ship_address" do
|
|
@@ -30,7 +30,7 @@ module Spree
|
|
|
30
30
|
end
|
|
31
31
|
end
|
|
32
32
|
|
|
33
|
-
context "when :
|
|
33
|
+
context "when tax_using_ship_address: false" do
|
|
34
34
|
before { Spree::Config.set(tax_using_ship_address: false) }
|
|
35
35
|
|
|
36
36
|
it "should calculate using bill_address" do
|