solidus_core 2.0.3 → 2.1.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/README.md +62 -3
- data/app/assets/javascripts/spree.js.coffee.erb +4 -1
- data/app/helpers/spree/base_helper.rb +7 -48
- data/app/models/spree/address.rb +5 -1
- data/app/models/spree/adjustment.rb +3 -3
- data/app/models/spree/app_configuration.rb +13 -0
- data/app/models/spree/calculator.rb +3 -2
- data/app/models/spree/calculator/default_tax.rb +6 -10
- data/app/models/spree/calculator/flat_percent_item_total.rb +0 -4
- data/app/models/spree/calculator/flat_rate.rb +0 -4
- data/app/models/spree/calculator/flexi_rate.rb +0 -4
- data/app/models/spree/calculator/free_shipping.rb +0 -3
- data/app/models/spree/calculator/percent_on_line_item.rb +0 -4
- data/app/models/spree/calculator/percent_per_item.rb +0 -4
- data/app/models/spree/calculator/price_sack.rb +0 -4
- data/app/models/spree/calculator/returns/default_refund_amount.rb +0 -3
- data/app/models/spree/calculator/shipping/flat_percent_item_total.rb +0 -4
- data/app/models/spree/calculator/shipping/flat_rate.rb +0 -4
- data/app/models/spree/calculator/shipping/flexi_rate.rb +0 -4
- data/app/models/spree/calculator/shipping/per_item.rb +0 -4
- data/app/models/spree/calculator/shipping/price_sack.rb +0 -4
- data/app/models/spree/calculator/tiered_flat_rate.rb +0 -4
- data/app/models/spree/calculator/tiered_percent.rb +0 -4
- data/app/models/spree/credit_card.rb +27 -14
- data/app/models/spree/gateway.rb +4 -0
- data/app/models/spree/inventory_unit.rb +2 -0
- data/app/models/spree/line_item.rb +31 -26
- data/app/models/spree/option_type.rb +0 -3
- data/app/models/spree/order.rb +28 -31
- data/app/models/spree/order/checkout.rb +0 -2
- data/app/models/spree/order_contents.rb +0 -45
- data/app/models/spree/order_merger.rb +6 -6
- data/app/models/spree/order_update_attributes.rb +0 -2
- data/app/models/spree/order_updater.rb +91 -13
- data/app/models/spree/payment.rb +9 -2
- data/app/models/spree/payment/processing.rb +15 -9
- data/app/models/spree/payment_method.rb +48 -5
- data/app/models/spree/price.rb +7 -9
- data/app/models/spree/product.rb +1 -25
- data/app/models/spree/promotion.rb +22 -14
- data/app/models/spree/promotion/actions/create_adjustment.rb +12 -1
- data/app/models/spree/promotion/actions/create_item_adjustments.rb +15 -1
- data/app/models/spree/promotion/actions/create_quantity_adjustments.rb +5 -3
- data/app/models/spree/promotion/actions/free_shipping.rb +14 -0
- data/app/models/spree/promotion/rules/taxon.rb +7 -2
- data/app/models/spree/promotion/rules/user_role.rb +43 -0
- data/app/models/spree/promotion_action.rb +19 -2
- data/app/models/spree/promotion_handler/coupon.rb +1 -4
- data/app/models/spree/promotion_handler/free_shipping.rb +22 -17
- data/app/models/spree/promotion_rule_role.rb +6 -0
- data/app/models/spree/property.rb +0 -3
- data/app/models/spree/return_authorization.rb +2 -0
- data/app/models/spree/shipment.rb +5 -21
- data/app/models/spree/shipping_method.rb +23 -2
- data/app/models/spree/shipping_rate.rb +3 -0
- data/app/models/spree/stock/estimator.rb +1 -1
- data/app/models/spree/stock_location.rb +3 -0
- data/app/models/spree/store.rb +7 -0
- data/app/models/spree/tax/item_adjuster.rb +27 -12
- data/app/models/spree/tax/order_adjuster.rb +2 -5
- data/app/models/spree/tax/tax_helpers.rb +4 -8
- data/app/models/spree/tax_rate.rb +1 -15
- data/app/models/spree/taxon.rb +0 -3
- data/app/models/spree/transfer_item.rb +1 -1
- data/app/models/spree/user_class_handle.rb +14 -9
- data/app/models/spree/variant/pricing_options.rb +1 -1
- data/app/models/spree/wallet/add_payment_sources_to_wallet.rb +1 -1
- data/app/models/spree/zone.rb +20 -13
- data/config/locales/en.yml +144 -62
- data/db/migrate/20120831092320_spree_one_two.rb +0 -7
- data/db/migrate/20150723224133_remove_unnecessary_indexes.rb +0 -2
- data/db/migrate/20160924135758_remove_is_default_from_prices.rb +5 -0
- data/db/migrate/20161009141333_remove_currency_from_line_items.rb +5 -0
- data/db/migrate/20161014221052_add_available_to_columns_and_remove_display_on_from_payment_methods.rb +28 -0
- data/db/migrate/20161123154034_add_available_to_users_and_remove_display_on_from_shipping_methods.rb +20 -0
- data/lib/generators/spree/custom_user/templates/authentication_helpers.rb.tt +4 -0
- data/lib/generators/spree/dummy/dummy_generator.rb +0 -2
- data/lib/spree/core.rb +0 -5
- data/lib/spree/core/controller_helpers/pricing.rb +2 -1
- data/lib/spree/core/engine.rb +14 -0
- data/lib/spree/core/version.rb +1 -1
- data/lib/spree/deprecation.rb +1 -1
- data/lib/spree/localized_number.rb +3 -2
- data/lib/spree/permission_sets/configuration_display.rb +0 -1
- data/lib/spree/permission_sets/configuration_management.rb +0 -1
- data/lib/spree/permission_sets/product_display.rb +0 -1
- data/lib/spree/permission_sets/product_management.rb +0 -1
- data/lib/spree/permission_sets/user_management.rb +2 -4
- data/lib/spree/permitted_attributes.rb +3 -2
- data/lib/spree/testing_support/capybara_ext.rb +0 -12
- data/lib/spree/testing_support/factories/address_factory.rb +1 -1
- data/lib/spree/testing_support/factories/line_item_factory.rb +0 -1
- data/lib/spree/testing_support/factories/payment_factory.rb +4 -0
- data/lib/spree/testing_support/factories/payment_method_factory.rb +8 -1
- data/lib/spree/testing_support/factories/user_factory.rb +2 -2
- data/solidus_core.gemspec +4 -3
- data/spec/helpers/base_helper_spec.rb +0 -40
- data/spec/lib/spree/core/controller_helpers/pricing_spec.rb +16 -0
- data/spec/lib/spree/core/importer/order_spec.rb +27 -18
- data/spec/lib/spree/core/price_migrator_spec.rb +3 -1
- data/spec/lib/spree/core/testing_support/factories/order_factory_spec.rb +16 -0
- data/spec/lib/spree/core/unreturned_item_charger_spec.rb +0 -2
- data/spec/lib/tasks/exchanges_spec.rb +4 -2
- data/spec/lib/tasks/migrations/create_vat_prices_spec.rb +5 -3
- data/spec/models/spree/adjustment_spec.rb +136 -0
- data/spec/models/spree/calculator/default_tax_spec.rb +13 -7
- data/spec/models/spree/calculator/flat_percent_item_total_spec.rb +3 -0
- data/spec/models/spree/calculator/flat_rate_spec.rb +3 -0
- data/spec/models/spree/calculator/flexi_rate_spec.rb +3 -0
- data/spec/models/spree/calculator/free_shipping_spec.rb +6 -0
- data/spec/models/spree/calculator/percent_on_line_item_spec.rb +9 -4
- data/spec/models/spree/calculator/percent_per_item_spec.rb +10 -0
- data/spec/models/spree/calculator/price_sack_spec.rb +3 -0
- data/spec/models/spree/calculator/refunds/default_refund_amount_spec.rb +3 -0
- data/spec/models/spree/calculator/shipping/flat_percent_item_total_spec.rb +3 -0
- data/spec/models/spree/calculator/shipping/flat_rate_spec.rb +3 -0
- data/spec/models/spree/calculator/shipping/flexi_rate_spec.rb +3 -0
- data/spec/models/spree/calculator/shipping/per_item_spec.rb +3 -0
- data/spec/models/spree/calculator/shipping/price_sack_spec.rb +4 -1
- data/spec/models/spree/calculator/tiered_flat_rate_spec.rb +3 -0
- data/spec/models/spree/calculator/tiered_percent_spec.rb +3 -0
- data/spec/models/spree/credit_card_spec.rb +27 -1
- data/spec/models/spree/line_item_spec.rb +58 -65
- data/spec/models/spree/order/checkout_spec.rb +2 -1
- data/spec/models/spree/order/payment_spec.rb +9 -10
- data/spec/models/spree/order/tax_spec.rb +22 -7
- data/spec/models/spree/order/updating_spec.rb +1 -3
- data/spec/models/spree/order_cancellations_spec.rb +6 -4
- data/spec/models/spree/order_contents_spec.rb +34 -50
- data/spec/models/spree/order_inventory_spec.rb +3 -5
- data/spec/models/spree/order_merger_spec.rb +20 -0
- data/spec/models/spree/order_spec.rb +28 -64
- data/spec/models/spree/order_update_attributes_spec.rb +1 -5
- data/spec/models/spree/order_updater_spec.rb +251 -0
- data/spec/models/spree/payment_method_spec.rb +178 -28
- data/spec/models/spree/payment_spec.rb +35 -19
- data/spec/models/spree/permission_sets/configuration_display.rb +0 -4
- data/spec/models/spree/permission_sets/configuration_management_spec.rb +0 -2
- data/spec/models/spree/permission_sets/product_display_spec.rb +0 -4
- data/spec/models/spree/permission_sets/product_management_spec.rb +0 -2
- data/spec/models/spree/permission_sets/user_management_spec.rb +9 -2
- data/spec/models/spree/price_spec.rb +16 -1
- data/spec/models/spree/product_spec.rb +0 -75
- data/spec/models/spree/promotion/actions/create_adjustment_spec.rb +20 -0
- data/spec/models/spree/promotion/actions/create_item_adjustments_spec.rb +39 -15
- data/spec/models/spree/promotion/actions/create_quantity_adjustments_spec.rb +203 -22
- data/spec/models/spree/promotion/actions/free_shipping_spec.rb +22 -3
- data/spec/models/spree/promotion/rules/taxon_spec.rb +26 -0
- data/spec/models/spree/promotion/rules/user_role_spec.rb +86 -0
- data/spec/models/spree/promotion_action_spec.rb +38 -0
- data/spec/models/spree/promotion_handler/coupon_spec.rb +36 -33
- data/spec/models/spree/promotion_handler/free_shipping_spec.rb +21 -22
- data/spec/models/spree/promotion_spec.rb +46 -6
- data/spec/models/spree/reimbursement_spec.rb +1 -1
- data/spec/models/spree/reimbursement_tax_calculator_spec.rb +2 -2
- data/spec/models/spree/shipment_spec.rb +68 -50
- data/spec/models/spree/shipping_method_spec.rb +41 -0
- data/spec/models/spree/shipping_rate_spec.rb +9 -3
- data/spec/models/spree/stock/estimator_spec.rb +4 -2
- data/spec/models/spree/store_credit_spec.rb +3 -3
- data/spec/models/spree/tax/item_adjuster_spec.rb +31 -21
- data/spec/models/spree/tax/order_adjuster_spec.rb +6 -10
- data/spec/models/spree/tax/taxation_integration_spec.rb +19 -0
- data/spec/models/spree/tax_rate_spec.rb +5 -26
- data/spec/models/spree/transfer_item_spec.rb +11 -0
- data/spec/models/spree/variant/pricing_options_spec.rb +7 -17
- data/spec/models/spree/variant_spec.rb +2 -4
- data/spec/models/spree/zone_spec.rb +60 -20
- data/spec/shared_examples/calculator_shared_examples.rb +8 -0
- metadata +19 -24
- data/app/models/spree/item_adjustments.rb +0 -89
- data/app/models/spree/option_type_prototype.rb +0 -6
- data/app/models/spree/property_prototype.rb +0 -6
- data/app/models/spree/prototype.rb +0 -14
- data/app/models/spree/prototype_taxon.rb +0 -6
- data/app/models/spree/tracker.rb +0 -8
- data/db/migrate/20150128032538_remove_environment_from_tracker.rb +0 -6
- data/lib/generators/spree/dummy/templates/initializers/custom_user.rb +0 -1
- data/lib/spree/core/delegate_belongs_to.rb +0 -94
- data/lib/spree/testing_support/factories/prototype_factory.rb +0 -8
- data/lib/spree/testing_support/factories/tracker_factory.rb +0 -6
- data/spec/lib/spree/core/delegate_belongs_to_spec.rb +0 -24
- data/spec/lib/spree/core/testing_support/factories/prototype_factory_spec.rb +0 -12
- data/spec/lib/spree/core/testing_support/factories/tracker_factory_spec.rb +0 -12
- data/spec/models/spree/item_adjustments_spec.rb +0 -306
- data/spec/models/spree/tracker_spec.rb +0 -21
|
@@ -20,8 +20,15 @@ describe Spree::PermissionSets::UserManagement do
|
|
|
20
20
|
it { is_expected.to be_able_to(:orders, Spree.user_class) }
|
|
21
21
|
it { is_expected.to be_able_to(:items, Spree.user_class) }
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
context 'when the user does not have a role' do
|
|
24
|
+
let(:user) { create(:user) }
|
|
25
|
+
it { is_expected.to be_able_to(:update_email, user) }
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
context 'when the user has a role' do
|
|
29
|
+
let(:user) { create(:user, spree_roles: [create(:role)]) }
|
|
30
|
+
it { is_expected.not_to be_able_to(:update_email, user) }
|
|
31
|
+
end
|
|
25
32
|
|
|
26
33
|
it { is_expected.not_to be_able_to(:delete, Spree.user_class) }
|
|
27
34
|
it { is_expected.not_to be_able_to(:destroy, Spree.user_class) }
|
|
@@ -55,6 +55,12 @@ describe Spree::Price, type: :model do
|
|
|
55
55
|
it { is_expected.to be_valid }
|
|
56
56
|
end
|
|
57
57
|
|
|
58
|
+
context 'when country iso is an empty string' do
|
|
59
|
+
let(:country_iso) { "" }
|
|
60
|
+
|
|
61
|
+
it { is_expected.to be_valid }
|
|
62
|
+
end
|
|
63
|
+
|
|
58
64
|
context 'when country iso is a country code' do
|
|
59
65
|
let!(:country) { create(:country, iso: "DE") }
|
|
60
66
|
let(:country_iso) { "DE" }
|
|
@@ -69,9 +75,18 @@ describe Spree::Price, type: :model do
|
|
|
69
75
|
end
|
|
70
76
|
end
|
|
71
77
|
|
|
78
|
+
describe "country_iso=" do
|
|
79
|
+
let(:price) { Spree::Price.new(country_iso: "de") }
|
|
80
|
+
|
|
81
|
+
it "assigns nil if passed nil" do
|
|
82
|
+
price.country_iso = nil
|
|
83
|
+
expect(price.country_iso).to be_nil
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
72
87
|
describe '#country' do
|
|
73
88
|
let!(:country) { create(:country, iso: "DE") }
|
|
74
|
-
let(:price) { create(:price, country_iso: "DE"
|
|
89
|
+
let(:price) { create(:price, country_iso: "DE") }
|
|
75
90
|
|
|
76
91
|
it 'returns the country object' do
|
|
77
92
|
expect(price.country).to eq(country)
|
|
@@ -429,81 +429,6 @@ describe Spree::Product, type: :model do
|
|
|
429
429
|
end
|
|
430
430
|
end
|
|
431
431
|
|
|
432
|
-
context '#create' do
|
|
433
|
-
let!(:prototype) { create(:prototype) }
|
|
434
|
-
let!(:product) { Spree::Product.new(name: "Foo", price: 1.99, shipping_category_id: create(:shipping_category).id) }
|
|
435
|
-
|
|
436
|
-
before { product.prototype_id = prototype.id }
|
|
437
|
-
|
|
438
|
-
context "when prototype is supplied" do
|
|
439
|
-
it "should create properties based on the prototype" do
|
|
440
|
-
product.save
|
|
441
|
-
expect(product.properties.count).to eq(1)
|
|
442
|
-
end
|
|
443
|
-
end
|
|
444
|
-
|
|
445
|
-
context "when prototype with option types is supplied" do
|
|
446
|
-
def build_option_type_with_values(name, values)
|
|
447
|
-
ot = create(:option_type, name: name)
|
|
448
|
-
values.each do |val|
|
|
449
|
-
ot.option_values.create(name: val.downcase, presentation: val)
|
|
450
|
-
end
|
|
451
|
-
ot
|
|
452
|
-
end
|
|
453
|
-
|
|
454
|
-
let(:prototype) do
|
|
455
|
-
size = build_option_type_with_values("size", %w(Small Medium Large))
|
|
456
|
-
create(:prototype, name: "Size", option_types: [size])
|
|
457
|
-
end
|
|
458
|
-
|
|
459
|
-
let(:option_values_hash) do
|
|
460
|
-
hash = {}
|
|
461
|
-
prototype.option_types.each do |i|
|
|
462
|
-
hash[i.id.to_s] = i.option_value_ids
|
|
463
|
-
end
|
|
464
|
-
hash
|
|
465
|
-
end
|
|
466
|
-
|
|
467
|
-
it "should create option types based on the prototype" do
|
|
468
|
-
product.save
|
|
469
|
-
expect(product.option_type_ids.length).to eq(1)
|
|
470
|
-
expect(product.option_type_ids).to eq(prototype.option_type_ids)
|
|
471
|
-
end
|
|
472
|
-
|
|
473
|
-
it "should create product option types based on the prototype" do
|
|
474
|
-
product.save
|
|
475
|
-
expect(product.product_option_types.pluck(:option_type_id)).to eq(prototype.option_type_ids)
|
|
476
|
-
end
|
|
477
|
-
|
|
478
|
-
it "should create variants from an option values hash with one option type" do
|
|
479
|
-
product.option_values_hash = option_values_hash
|
|
480
|
-
product.save
|
|
481
|
-
expect(product.variants.length).to eq(3)
|
|
482
|
-
end
|
|
483
|
-
|
|
484
|
-
it "should still create variants when option_values_hash is given but prototype id is nil" do
|
|
485
|
-
product.option_values_hash = option_values_hash
|
|
486
|
-
product.prototype_id = nil
|
|
487
|
-
product.save
|
|
488
|
-
expect(product.option_type_ids.length).to eq(1)
|
|
489
|
-
expect(product.option_type_ids).to eq(prototype.option_type_ids)
|
|
490
|
-
expect(product.variants.length).to eq(3)
|
|
491
|
-
end
|
|
492
|
-
|
|
493
|
-
it "should create variants from an option values hash with multiple option types" do
|
|
494
|
-
color = build_option_type_with_values("color", %w(Red Green Blue))
|
|
495
|
-
logo = build_option_type_with_values("logo", %w(Ruby Rails Nginx))
|
|
496
|
-
option_values_hash[color.id.to_s] = color.option_value_ids
|
|
497
|
-
option_values_hash[logo.id.to_s] = logo.option_value_ids
|
|
498
|
-
product.option_values_hash = option_values_hash
|
|
499
|
-
product.save
|
|
500
|
-
product.reload
|
|
501
|
-
expect(product.option_type_ids.length).to eq(3)
|
|
502
|
-
expect(product.variants.length).to eq(27)
|
|
503
|
-
end
|
|
504
|
-
end
|
|
505
|
-
end
|
|
506
|
-
|
|
507
432
|
context "#images" do
|
|
508
433
|
let(:product) { create(:product) }
|
|
509
434
|
let(:image) { File.open(File.expand_path('../../../fixtures/thinking-cat.jpg', __FILE__)) }
|
|
@@ -58,6 +58,26 @@ describe Spree::Promotion::Actions::CreateAdjustment, type: :model do
|
|
|
58
58
|
end
|
|
59
59
|
end
|
|
60
60
|
|
|
61
|
+
describe '#remove_from' do
|
|
62
|
+
let(:action) { promotion.actions.first! }
|
|
63
|
+
let(:promotion) { create(:promotion, :with_order_adjustment) }
|
|
64
|
+
|
|
65
|
+
let!(:unrelated_adjustment) { create(:adjustment, order: order, source: nil) }
|
|
66
|
+
|
|
67
|
+
before do
|
|
68
|
+
action.perform(payload)
|
|
69
|
+
@action_adjustment = order.adjustments.where(source: action).first!
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it 'removes the action adjustment' do
|
|
73
|
+
expect(order.adjustments).to match_array([unrelated_adjustment, @action_adjustment])
|
|
74
|
+
|
|
75
|
+
action.remove_from(order)
|
|
76
|
+
|
|
77
|
+
expect(order.adjustments).to eq([unrelated_adjustment])
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
61
81
|
context "#destroy" do
|
|
62
82
|
before(:each) do
|
|
63
83
|
action.calculator = Spree::Calculator::FlatRate.new(preferred_amount: 10)
|
|
@@ -4,11 +4,11 @@ module Spree
|
|
|
4
4
|
class Promotion
|
|
5
5
|
module Actions
|
|
6
6
|
describe CreateItemAdjustments, type: :model do
|
|
7
|
-
let(:order) { create(:
|
|
7
|
+
let(:order) { create(:order_with_line_items, line_items_count: 1) }
|
|
8
8
|
let(:promotion) { create(:promotion, :with_line_item_adjustment, adjustment_rate: adjustment_amount) }
|
|
9
9
|
let(:adjustment_amount) { 10 }
|
|
10
10
|
let(:action) { promotion.actions.first! }
|
|
11
|
-
let
|
|
11
|
+
let(:line_item) { order.line_items.to_a.first }
|
|
12
12
|
let(:payload) { { order: order, promotion: promotion } }
|
|
13
13
|
|
|
14
14
|
before do
|
|
@@ -122,32 +122,56 @@ module Spree
|
|
|
122
122
|
end
|
|
123
123
|
end
|
|
124
124
|
|
|
125
|
+
describe '#remove_from' do
|
|
126
|
+
# this adjustment should not get removed
|
|
127
|
+
let!(:other_adjustment) { create(:adjustment, adjustable: line_item, order: order, source: nil) }
|
|
128
|
+
|
|
129
|
+
before do
|
|
130
|
+
action.perform(payload)
|
|
131
|
+
@action_adjustment = line_item.adjustments.where(source: action).first!
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
it 'removes the action adjustment' do
|
|
135
|
+
expect(line_item.adjustments).to match_array([other_adjustment, @action_adjustment])
|
|
136
|
+
|
|
137
|
+
action.remove_from(order)
|
|
138
|
+
|
|
139
|
+
expect(line_item.adjustments).to eq([other_adjustment])
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
125
143
|
context "#destroy" do
|
|
126
144
|
let!(:action) { promotion.actions.first }
|
|
127
145
|
let(:other_action) { other_promotion.actions.first }
|
|
128
146
|
let(:promotion) { create(:promotion, :with_line_item_adjustment) }
|
|
129
147
|
let(:other_promotion) { create(:promotion, :with_line_item_adjustment) }
|
|
130
148
|
|
|
131
|
-
|
|
132
|
-
order
|
|
133
|
-
action.adjustments.create!(label: "Check", amount: 0, order: order, adjustable: order)
|
|
149
|
+
context 'with incomplete orders' do
|
|
150
|
+
let(:order) { create(:order) }
|
|
134
151
|
|
|
135
|
-
|
|
136
|
-
action
|
|
137
|
-
|
|
152
|
+
it 'destroys adjustments' do
|
|
153
|
+
order.adjustments.create!(label: 'Check', amount: 0, order: order, source: action)
|
|
154
|
+
|
|
155
|
+
expect {
|
|
156
|
+
action.destroy
|
|
157
|
+
}.to change { Adjustment.count }.by(-1)
|
|
158
|
+
end
|
|
138
159
|
end
|
|
139
160
|
|
|
140
|
-
|
|
141
|
-
order
|
|
142
|
-
adjustment = action.adjustments.create!(label: "Check", amount: 0, order: order, adjustable: order)
|
|
161
|
+
context 'with complete orders' do
|
|
162
|
+
let(:order) { create(:completed_order_with_totals) }
|
|
143
163
|
|
|
144
|
-
|
|
145
|
-
action
|
|
146
|
-
|
|
164
|
+
it 'nullifies adjustments for completed orders' do
|
|
165
|
+
adjustment = order.adjustments.create!(label: 'Check', amount: 0, order: order, source: action)
|
|
166
|
+
|
|
167
|
+
expect {
|
|
168
|
+
action.destroy
|
|
169
|
+
}.to change { adjustment.reload.source_id }.from(action.id).to nil
|
|
170
|
+
end
|
|
147
171
|
end
|
|
148
172
|
|
|
149
173
|
it "doesnt mess with unrelated adjustments" do
|
|
150
|
-
|
|
174
|
+
order.adjustments.create!(label: "Check", amount: 0, order: order, source: action)
|
|
151
175
|
|
|
152
176
|
expect {
|
|
153
177
|
action.destroy
|
|
@@ -4,36 +4,53 @@ module Spree::Promotion::Actions
|
|
|
4
4
|
RSpec.describe CreateQuantityAdjustments do
|
|
5
5
|
let(:action) { CreateQuantityAdjustments.create!(calculator: calculator, promotion: promotion) }
|
|
6
6
|
|
|
7
|
-
let(:order)
|
|
7
|
+
let(:order) do
|
|
8
|
+
create(
|
|
9
|
+
:order_with_line_items,
|
|
10
|
+
line_items_attributes: line_items_attributes
|
|
11
|
+
)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
let(:line_items_attributes) do
|
|
15
|
+
[
|
|
16
|
+
{ price: 10, quantity: quantity }
|
|
17
|
+
]
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
let(:quantity) { 1 }
|
|
8
21
|
let(:promotion) { FactoryGirl.create :promotion }
|
|
9
22
|
|
|
10
23
|
describe "#compute_amount" do
|
|
11
24
|
subject { action.compute_amount(line_item) }
|
|
12
25
|
|
|
13
|
-
let!(:item_a) { FactoryGirl.create :line_item, order: order, quantity: quantity, price: 10 }
|
|
14
|
-
|
|
15
26
|
context "with a flat rate adjustment" do
|
|
16
27
|
let(:calculator) { FactoryGirl.create :flat_rate_calculator, preferred_amount: 5 }
|
|
17
28
|
|
|
18
29
|
context "with a quantity group of 2" do
|
|
19
|
-
let(:line_item) {
|
|
30
|
+
let(:line_item) { order.line_items.first }
|
|
31
|
+
|
|
20
32
|
before { action.preferred_group_size = 2 }
|
|
33
|
+
|
|
21
34
|
context "and an item with a quantity of 0" do
|
|
22
35
|
let(:quantity) { 0 }
|
|
23
36
|
it { is_expected.to eq 0 }
|
|
24
37
|
end
|
|
38
|
+
|
|
25
39
|
context "and an item with a quantity of 1" do
|
|
26
40
|
let(:quantity) { 1 }
|
|
27
41
|
it { is_expected.to eq 0 }
|
|
28
42
|
end
|
|
43
|
+
|
|
29
44
|
context "and an item with a quantity of 2" do
|
|
30
45
|
let(:quantity) { 2 }
|
|
31
46
|
it { is_expected.to eq(-10) }
|
|
32
47
|
end
|
|
48
|
+
|
|
33
49
|
context "and an item with a quantity of 3" do
|
|
34
50
|
let(:quantity) { 3 }
|
|
35
51
|
it { is_expected.to eq(-10) }
|
|
36
52
|
end
|
|
53
|
+
|
|
37
54
|
context "and an item with a quantity of 4" do
|
|
38
55
|
let(:quantity) { 4 }
|
|
39
56
|
it { is_expected.to eq(-20) }
|
|
@@ -41,36 +58,51 @@ module Spree::Promotion::Actions
|
|
|
41
58
|
end
|
|
42
59
|
|
|
43
60
|
context "with a quantity group of 3" do
|
|
44
|
-
let(:quantity) { 2 }
|
|
45
|
-
let!(:item_b) { FactoryGirl.create :line_item, order: order, quantity: 1 }
|
|
46
|
-
let!(:item_c) { FactoryGirl.create :line_item, order: order, quantity: 1 }
|
|
47
61
|
before { action.preferred_group_size = 3 }
|
|
62
|
+
|
|
48
63
|
context "and 2x item A, 1x item B and 1x item C" do
|
|
64
|
+
let(:line_items_attributes) do
|
|
65
|
+
[
|
|
66
|
+
{ price: 10, quantity: 2 },
|
|
67
|
+
{ price: 10, quantity: 1 },
|
|
68
|
+
{ price: 10, quantity: 1 },
|
|
69
|
+
]
|
|
70
|
+
end
|
|
71
|
+
|
|
49
72
|
before { action.perform({ order: order, promotion: promotion }) }
|
|
73
|
+
|
|
50
74
|
describe "the adjustment for the first item" do
|
|
51
|
-
let(:line_item) {
|
|
75
|
+
let(:line_item) { order.line_items.first }
|
|
52
76
|
it { is_expected.to eq(-10) }
|
|
53
77
|
end
|
|
54
78
|
describe "the adjustment for the second item" do
|
|
55
|
-
let(:line_item) {
|
|
79
|
+
let(:line_item) { order.line_items.second }
|
|
56
80
|
it { is_expected.to eq(-5) }
|
|
57
81
|
end
|
|
58
82
|
describe "the adjustment for the third item" do
|
|
59
|
-
let(:line_item) {
|
|
83
|
+
let(:line_item) { order.line_items.third }
|
|
60
84
|
it { is_expected.to eq 0 }
|
|
61
85
|
end
|
|
62
86
|
end
|
|
63
87
|
end
|
|
64
88
|
|
|
65
89
|
context "with multiple orders using the same action" do
|
|
66
|
-
let(:
|
|
67
|
-
|
|
90
|
+
let(:other_order) do
|
|
91
|
+
create(
|
|
92
|
+
:order_with_line_items,
|
|
93
|
+
line_items_attributes: [
|
|
94
|
+
{ quantity: 3 }
|
|
95
|
+
]
|
|
96
|
+
)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
let(:line_item) { other_order.line_items.first }
|
|
100
|
+
|
|
68
101
|
before do
|
|
69
102
|
action.preferred_group_size = 2
|
|
70
|
-
other_order = FactoryGirl.create :order
|
|
71
|
-
FactoryGirl.create :line_item, order: other_order, quantity: 3
|
|
72
103
|
action.perform({ order: other_order, promotion: promotion })
|
|
73
104
|
end
|
|
105
|
+
|
|
74
106
|
it { is_expected.to eq(-10) }
|
|
75
107
|
end
|
|
76
108
|
end
|
|
@@ -78,38 +110,187 @@ module Spree::Promotion::Actions
|
|
|
78
110
|
context "with a percentage based adjustment" do
|
|
79
111
|
let(:calculator) { FactoryGirl.create :percent_on_item_calculator, preferred_percent: 10 }
|
|
80
112
|
|
|
113
|
+
let(:line_items_attributes) do
|
|
114
|
+
[
|
|
115
|
+
{ price: 10, quantity: 1 }.merge(line_one_options),
|
|
116
|
+
{ price: 10, quantity: 1 }.merge(line_two_options),
|
|
117
|
+
]
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
let(:line_one_options) { {} }
|
|
121
|
+
let(:line_two_options) { {} }
|
|
122
|
+
|
|
81
123
|
context "with a quantity group of 3" do
|
|
82
124
|
before do
|
|
83
125
|
action.preferred_group_size = 3
|
|
84
126
|
action.perform({ order: order, promotion: promotion })
|
|
85
127
|
end
|
|
128
|
+
|
|
86
129
|
context "and 2x item A and 1x item B" do
|
|
87
|
-
let(:
|
|
88
|
-
|
|
130
|
+
let(:line_one_options) { { quantity: 2 } }
|
|
131
|
+
|
|
89
132
|
describe "the adjustment for the first item" do
|
|
90
|
-
let(:line_item) {
|
|
133
|
+
let(:line_item) { order.line_items.first }
|
|
91
134
|
it { is_expected.to eq(-2) }
|
|
92
135
|
end
|
|
93
136
|
describe "the adjustment for the second item" do
|
|
94
|
-
let(:line_item) {
|
|
137
|
+
let(:line_item) { order.line_items.second }
|
|
95
138
|
it { is_expected.to eq(-1) }
|
|
96
139
|
end
|
|
97
140
|
end
|
|
98
141
|
|
|
99
142
|
context "and the items cost different amounts" do
|
|
100
|
-
let(:
|
|
101
|
-
let
|
|
143
|
+
let(:line_one_options) { { quantity: 3 } }
|
|
144
|
+
let(:line_two_options) { { price: 20 } }
|
|
145
|
+
|
|
102
146
|
describe "the adjustment for the first item" do
|
|
103
|
-
let(:line_item) {
|
|
147
|
+
let(:line_item) { order.line_items.first }
|
|
104
148
|
it { is_expected.to eq(-3) }
|
|
105
149
|
end
|
|
106
150
|
describe "the adjustment for the second item" do
|
|
107
|
-
let(:line_item) {
|
|
151
|
+
let(:line_item) { order.line_items.second }
|
|
108
152
|
it { is_expected.to eq 0 }
|
|
109
153
|
end
|
|
110
154
|
end
|
|
111
155
|
end
|
|
112
156
|
end
|
|
157
|
+
|
|
158
|
+
context "with a tiered percentage based adjustment" do
|
|
159
|
+
let(:tiers) do
|
|
160
|
+
{
|
|
161
|
+
20 => 20,
|
|
162
|
+
40 => 30
|
|
163
|
+
}
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
let(:calculator) do
|
|
167
|
+
Spree::Calculator::TieredPercent.create(preferred_base_percent: 10, preferred_tiers: tiers)
|
|
168
|
+
end
|
|
169
|
+
let(:line_items_attributes) do
|
|
170
|
+
[
|
|
171
|
+
{ price: 10, quantity: 1 }.merge(line_one_options),
|
|
172
|
+
{ price: 10, quantity: 1 }.merge(line_two_options),
|
|
173
|
+
]
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
let(:line_one_options) { {} }
|
|
177
|
+
let(:line_two_options) { {} }
|
|
178
|
+
|
|
179
|
+
context "with a quantity group of 3" do
|
|
180
|
+
before do
|
|
181
|
+
action.preferred_group_size = 3
|
|
182
|
+
action.perform({ order: order, promotion: promotion })
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
context "and 2x item A and 1x item B" do
|
|
186
|
+
let(:line_one_options) { { quantity: 2 } }
|
|
187
|
+
|
|
188
|
+
context "when amount falls within the first tier" do
|
|
189
|
+
describe "the adjustment for the first item" do
|
|
190
|
+
let(:line_item) { order.line_items.first }
|
|
191
|
+
it { is_expected.to eq(-4) }
|
|
192
|
+
end
|
|
193
|
+
describe "the adjustment for the second item" do
|
|
194
|
+
let(:line_item) { order.line_items.second }
|
|
195
|
+
it { is_expected.to eq(-2) }
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
context "when amount falls within the second tier" do
|
|
200
|
+
let(:line_two_options) { { price: 20 } }
|
|
201
|
+
|
|
202
|
+
describe "the adjustment for the first item" do
|
|
203
|
+
let(:line_item) { order.line_items.first }
|
|
204
|
+
it { is_expected.to eq(-6) }
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
describe "the adjustment for the second item" do
|
|
208
|
+
let(:line_item) { order.line_items.second }
|
|
209
|
+
it { is_expected.to eq(-6) }
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
# Regression test for https://github.com/solidusio/solidus/pull/1591
|
|
218
|
+
context "with unsaved line_item changes" do
|
|
219
|
+
let(:calculator) { FactoryGirl.create :flat_rate_calculator }
|
|
220
|
+
let(:line_item) { order.line_items.first }
|
|
221
|
+
|
|
222
|
+
before do
|
|
223
|
+
order.line_items.first.promo_total = -11
|
|
224
|
+
action.compute_amount(line_item)
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
it "doesn't reload the line_items association" do
|
|
228
|
+
expect(order.line_items.first.promo_total).to eq -11
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
# Regression test for https://github.com/solidusio/solidus/pull/1591
|
|
233
|
+
context "applied to the order" do
|
|
234
|
+
let(:calculator) { FactoryGirl.create :flat_rate_calculator }
|
|
235
|
+
|
|
236
|
+
before do
|
|
237
|
+
action.perform(order: order, promotion: promotion)
|
|
238
|
+
order.update!
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
it 'updates the order totals' do
|
|
242
|
+
expect(order).to have_attributes(
|
|
243
|
+
total: 100,
|
|
244
|
+
adjustment_total: -10
|
|
245
|
+
)
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
context "after updating item quantity" do
|
|
249
|
+
before do
|
|
250
|
+
order.line_items.first.update!(quantity: 2, price: 30)
|
|
251
|
+
order.update!
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
it 'updates the order totals' do
|
|
255
|
+
expect(order).to have_attributes(
|
|
256
|
+
total: 140,
|
|
257
|
+
adjustment_total: -20
|
|
258
|
+
)
|
|
259
|
+
end
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
context "after updating promotion amount" do
|
|
263
|
+
before do
|
|
264
|
+
calculator.update!(preferred_amount: 5)
|
|
265
|
+
order.update!
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
it 'updates the order totals' do
|
|
269
|
+
expect(order).to have_attributes(
|
|
270
|
+
total: 105,
|
|
271
|
+
adjustment_total: -5
|
|
272
|
+
)
|
|
273
|
+
end
|
|
274
|
+
end
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
describe Spree::Promotion::Actions::CreateQuantityAdjustments::PartialLineItem do
|
|
278
|
+
let!(:item) { FactoryGirl.create :line_item, order: order, quantity: quantity, price: 10 }
|
|
279
|
+
let(:quantity) { 5 }
|
|
280
|
+
|
|
281
|
+
subject { described_class.new(item) }
|
|
282
|
+
|
|
283
|
+
it "has a reference to the parent order" do
|
|
284
|
+
expect(subject.order.id).to eq order.id
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
it "uses the `line_item.price` as a `line_item.amount`" do
|
|
288
|
+
expect(subject.amount).to eq item.price
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
it "has a currency" do
|
|
292
|
+
expect(subject.currency).to eq item.currency
|
|
293
|
+
end
|
|
113
294
|
end
|
|
114
295
|
end
|
|
115
296
|
end
|