solidus_core 1.0.2 → 1.0.3
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/CHANGELOG.md +1 -0
- data/Gemfile +3 -0
- data/Rakefile +16 -0
- data/script/rails +9 -0
- data/solidus_core.gemspec +48 -0
- data/spec/fixtures/thinking-cat.jpg +0 -0
- data/spec/helpers/base_helper_spec.rb +173 -0
- data/spec/helpers/order_helper_spec.rb +12 -0
- data/spec/helpers/products_helper_spec.rb +220 -0
- data/spec/helpers/taxons_helper_spec.rb +17 -0
- data/spec/lib/calculated_adjustments_spec.rb +7 -0
- data/spec/lib/i18n_spec.rb +123 -0
- data/spec/lib/search/base_spec.rb +86 -0
- data/spec/lib/search/variant_spec.rb +92 -0
- data/spec/lib/spree/core/controller_helpers/auth_spec.rb +66 -0
- data/spec/lib/spree/core/controller_helpers/order_spec.rb +92 -0
- data/spec/lib/spree/core/controller_helpers/search_spec.rb +17 -0
- data/spec/lib/spree/core/controller_helpers/store_spec.rb +16 -0
- data/spec/lib/spree/core/controller_helpers/strong_parameters_spec.rb +39 -0
- data/spec/lib/spree/core/current_store_spec.rb +36 -0
- data/spec/lib/spree/core/delegate_belongs_to_spec.rb +22 -0
- data/spec/lib/spree/core/importer/order_spec.rb +431 -0
- data/spec/lib/spree/core/role_configuration_spec.rb +138 -0
- data/spec/lib/spree/core/validators/email_spec.rb +48 -0
- data/spec/lib/spree/localized_number_spec.rb +38 -0
- data/spec/lib/spree/migrations_spec.rb +36 -0
- data/spec/lib/spree/money_spec.rb +127 -0
- data/spec/lib/tasks/exchanges_spec.rb +231 -0
- data/spec/lib/tasks/migrations/copy_shipped_shipments_to_cartons_spec.rb +115 -0
- data/spec/lib/tasks/order_capturing_spec.rb +56 -0
- data/spec/mailers/carton_mailer_spec.rb +43 -0
- data/spec/mailers/order_mailer_spec.rb +122 -0
- data/spec/mailers/reimbursement_mailer_spec.rb +40 -0
- data/spec/mailers/test_mailer_spec.rb +15 -0
- data/spec/models/spree/ability_spec.rb +276 -0
- data/spec/models/spree/address_spec.rb +250 -0
- data/spec/models/spree/adjustment_reason_spec.rb +13 -0
- data/spec/models/spree/adjustment_spec.rb +177 -0
- data/spec/models/spree/app_configuration_spec.rb +20 -0
- data/spec/models/spree/asset_spec.rb +24 -0
- data/spec/models/spree/calculator/default_tax_spec.rb +127 -0
- data/spec/models/spree/calculator/flat_percent_item_total_spec.rb +25 -0
- data/spec/models/spree/calculator/flat_rate_spec.rb +47 -0
- data/spec/models/spree/calculator/flexi_rate_spec.rb +41 -0
- data/spec/models/spree/calculator/percent_on_line_item_spec.rb +15 -0
- data/spec/models/spree/calculator/price_sack_spec.rb +30 -0
- data/spec/models/spree/calculator/refunds/default_refund_amount_spec.rb +51 -0
- data/spec/models/spree/calculator/shipping/flat_percent_item_total_spec.rb +23 -0
- data/spec/models/spree/calculator/shipping/flat_rate_spec.rb +13 -0
- data/spec/models/spree/calculator/shipping/flexi_rate_spec.rb +52 -0
- data/spec/models/spree/calculator/shipping/per_item_spec.rb +20 -0
- data/spec/models/spree/calculator/shipping/price_sack_spec.rb +30 -0
- data/spec/models/spree/calculator/tiered_flat_rate_spec.rb +36 -0
- data/spec/models/spree/calculator/tiered_percent_spec.rb +47 -0
- data/spec/models/spree/calculator_spec.rb +36 -0
- data/spec/models/spree/carton_spec.rb +133 -0
- data/spec/models/spree/classification_spec.rb +15 -0
- data/spec/models/spree/concerns/display_money_spec.rb +43 -0
- data/spec/models/spree/concerns/user_methods_spec.rb +41 -0
- data/spec/models/spree/credit_card_spec.rb +334 -0
- data/spec/models/spree/customer_return_spec.rb +276 -0
- data/spec/models/spree/exchange_spec.rb +79 -0
- data/spec/models/spree/gateway/bogus_simple.rb +20 -0
- data/spec/models/spree/gateway/bogus_spec.rb +13 -0
- data/spec/models/spree/gateway_spec.rb +82 -0
- data/spec/models/spree/inventory_unit_spec.rb +307 -0
- data/spec/models/spree/item_adjustments_spec.rb +256 -0
- data/spec/models/spree/line_item_spec.rb +191 -0
- data/spec/models/spree/option_type_spec.rb +14 -0
- data/spec/models/spree/option_value_spec.rb +22 -0
- data/spec/models/spree/order/address_spec.rb +50 -0
- data/spec/models/spree/order/adjustments_spec.rb +39 -0
- data/spec/models/spree/order/callbacks_spec.rb +42 -0
- data/spec/models/spree/order/checkout_spec.rb +902 -0
- data/spec/models/spree/order/currency_updater_spec.rb +32 -0
- data/spec/models/spree/order/finalizing_spec.rb +111 -0
- data/spec/models/spree/order/payment_spec.rb +210 -0
- data/spec/models/spree/order/risk_assessment_spec.rb +68 -0
- data/spec/models/spree/order/state_machine_spec.rb +221 -0
- data/spec/models/spree/order/tax_spec.rb +84 -0
- data/spec/models/spree/order/totals_spec.rb +24 -0
- data/spec/models/spree/order/updating_spec.rb +18 -0
- data/spec/models/spree/order/validations_spec.rb +15 -0
- data/spec/models/spree/order_cancellations_spec.rb +120 -0
- data/spec/models/spree/order_capturing_spec.rb +116 -0
- data/spec/models/spree/order_contents_spec.rb +265 -0
- data/spec/models/spree/order_inventory_spec.rb +228 -0
- data/spec/models/spree/order_mutex_spec.rb +85 -0
- data/spec/models/spree/order_promotion_spec.rb +31 -0
- data/spec/models/spree/order_shipping_spec.rb +247 -0
- data/spec/models/spree/order_spec.rb +1412 -0
- data/spec/models/spree/order_stock_location_spec.rb +18 -0
- data/spec/models/spree/order_updater_spec.rb +299 -0
- data/spec/models/spree/payment_method/store_credit_spec.rb +294 -0
- data/spec/models/spree/payment_method_spec.rb +96 -0
- data/spec/models/spree/payment_spec.rb +1044 -0
- data/spec/models/spree/permission_sets/base_spec.rb +12 -0
- data/spec/models/spree/permission_sets/configuration_display.rb +82 -0
- data/spec/models/spree/permission_sets/configuration_management_spec.rb +50 -0
- data/spec/models/spree/permission_sets/dashboard_display_spec.rb +22 -0
- data/spec/models/spree/permission_sets/order_display_spec.rb +49 -0
- data/spec/models/spree/permission_sets/order_management_spec.rb +36 -0
- data/spec/models/spree/permission_sets/product_display_spec.rb +60 -0
- data/spec/models/spree/permission_sets/product_management_spec.rb +40 -0
- data/spec/models/spree/permission_sets/promotion_display_spec.rb +34 -0
- data/spec/models/spree/permission_sets/promotion_management_spec.rb +26 -0
- data/spec/models/spree/permission_sets/report_display_spec.rb +24 -0
- data/spec/models/spree/permission_sets/restricted_transfer_management_spec.rb +132 -0
- data/spec/models/spree/permission_sets/stock_display_spec.rb +26 -0
- data/spec/models/spree/permission_sets/stock_management_spec.rb +24 -0
- data/spec/models/spree/permission_sets/user_display_spec.rb +36 -0
- data/spec/models/spree/permission_sets/user_management_spec.rb +28 -0
- data/spec/models/spree/preference_spec.rb +80 -0
- data/spec/models/spree/preferences/configuration_spec.rb +30 -0
- data/spec/models/spree/preferences/preferable_spec.rb +294 -0
- data/spec/models/spree/preferences/scoped_store_spec.rb +58 -0
- data/spec/models/spree/preferences/static_model_preferences_spec.rb +78 -0
- data/spec/models/spree/preferences/statically_configurable_spec.rb +60 -0
- data/spec/models/spree/preferences/store_spec.rb +39 -0
- data/spec/models/spree/price_spec.rb +42 -0
- data/spec/models/spree/product/scopes_spec.rb +148 -0
- data/spec/models/spree/product_duplicator_spec.rb +103 -0
- data/spec/models/spree/product_filter_spec.rb +26 -0
- data/spec/models/spree/product_property_spec.rb +20 -0
- data/spec/models/spree/product_spec.rb +437 -0
- data/spec/models/spree/promotion/actions/create_adjustment_spec.rb +96 -0
- data/spec/models/spree/promotion/actions/create_item_adjustments_spec.rb +165 -0
- data/spec/models/spree/promotion/actions/create_quantity_adjustments_spec.rb +115 -0
- data/spec/models/spree/promotion/actions/free_shipping_spec.rb +40 -0
- data/spec/models/spree/promotion/rules/first_order_spec.rb +75 -0
- data/spec/models/spree/promotion/rules/item_total_spec.rb +67 -0
- data/spec/models/spree/promotion/rules/nth_order_spec.rb +70 -0
- data/spec/models/spree/promotion/rules/one_use_per_user_spec.rb +42 -0
- data/spec/models/spree/promotion/rules/option_value_spec.rb +94 -0
- data/spec/models/spree/promotion/rules/product_spec.rb +143 -0
- data/spec/models/spree/promotion/rules/taxon_spec.rb +102 -0
- data/spec/models/spree/promotion/rules/user_logged_in_spec.rb +27 -0
- data/spec/models/spree/promotion/rules/user_spec.rb +37 -0
- data/spec/models/spree/promotion_builder_spec.rb +118 -0
- data/spec/models/spree/promotion_category_spec.rb +17 -0
- data/spec/models/spree/promotion_code/code_builder_spec.rb +79 -0
- data/spec/models/spree/promotion_code_spec.rb +187 -0
- data/spec/models/spree/promotion_handler/cart_spec.rb +114 -0
- data/spec/models/spree/promotion_handler/coupon_spec.rb +335 -0
- data/spec/models/spree/promotion_handler/free_shipping_spec.rb +47 -0
- data/spec/models/spree/promotion_handler/page_spec.rb +44 -0
- data/spec/models/spree/promotion_rule_spec.rb +28 -0
- data/spec/models/spree/promotion_spec.rb +767 -0
- data/spec/models/spree/refund_spec.rb +204 -0
- data/spec/models/spree/reimbursement/credit_spec.rb +36 -0
- data/spec/models/spree/reimbursement/reimbursement_type_engine_spec.rb +140 -0
- data/spec/models/spree/reimbursement/reimbursement_type_validator_spec.rb +83 -0
- data/spec/models/spree/reimbursement_performer_spec.rb +30 -0
- data/spec/models/spree/reimbursement_spec.rb +231 -0
- data/spec/models/spree/reimbursement_tax_calculator_spec.rb +51 -0
- data/spec/models/spree/reimbursement_type/credit_spec.rb +53 -0
- data/spec/models/spree/reimbursement_type/exchange_spec.rb +46 -0
- data/spec/models/spree/reimbursement_type/original_payment_spec.rb +107 -0
- data/spec/models/spree/reimbursement_type/store_credit_spec.rb +97 -0
- data/spec/models/spree/return_authorization_spec.rb +290 -0
- data/spec/models/spree/return_item/eligibility_validator/default_spec.rb +77 -0
- data/spec/models/spree/return_item/eligibility_validator/inventory_shipped_spec.rb +58 -0
- data/spec/models/spree/return_item/eligibility_validator/no_reimbursements_spec.rb +85 -0
- data/spec/models/spree/return_item/eligibility_validator/order_completed_spec.rb +32 -0
- data/spec/models/spree/return_item/eligibility_validator/rma_required_spec.rb +29 -0
- data/spec/models/spree/return_item/eligibility_validator/time_since_purchase_spec.rb +35 -0
- data/spec/models/spree/return_item/exchange_variant_eligibility/same_option_value_spec.rb +65 -0
- data/spec/models/spree/return_item/exchange_variant_eligibility/same_product_spec.rb +43 -0
- data/spec/models/spree/return_item_spec.rb +775 -0
- data/spec/models/spree/returns_calculator_spec.rb +14 -0
- data/spec/models/spree/shipment_spec.rb +709 -0
- data/spec/models/spree/shipping_calculator_spec.rb +45 -0
- data/spec/models/spree/shipping_method_spec.rb +88 -0
- data/spec/models/spree/shipping_rate_spec.rb +142 -0
- data/spec/models/spree/state_spec.rb +14 -0
- data/spec/models/spree/stock/availability_validator_spec.rb +83 -0
- data/spec/models/spree/stock/coordinator_spec.rb +116 -0
- data/spec/models/spree/stock/differentiator_spec.rb +39 -0
- data/spec/models/spree/stock/estimator_spec.rb +146 -0
- data/spec/models/spree/stock/inventory_unit_builder_spec.rb +38 -0
- data/spec/models/spree/stock/package_spec.rb +163 -0
- data/spec/models/spree/stock/packer_spec.rb +91 -0
- data/spec/models/spree/stock/prioritizer_spec.rb +125 -0
- data/spec/models/spree/stock/quantifier_spec.rb +115 -0
- data/spec/models/spree/stock/splitter/backordered_spec.rb +29 -0
- data/spec/models/spree/stock/splitter/base_spec.rb +21 -0
- data/spec/models/spree/stock/splitter/shipping_category_spec.rb +50 -0
- data/spec/models/spree/stock/splitter/weight_spec.rb +29 -0
- data/spec/models/spree/stock_item_spec.rb +426 -0
- data/spec/models/spree/stock_location_spec.rb +279 -0
- data/spec/models/spree/stock_movement_spec.rb +56 -0
- data/spec/models/spree/stock_transfer_spec.rb +290 -0
- data/spec/models/spree/store_credit_category_spec.rb +17 -0
- data/spec/models/spree/store_credit_event_spec.rb +314 -0
- data/spec/models/spree/store_credit_spec.rb +876 -0
- data/spec/models/spree/store_spec.rb +55 -0
- data/spec/models/spree/tax_category_spec.rb +27 -0
- data/spec/models/spree/tax_rate_spec.rb +378 -0
- data/spec/models/spree/taxon_spec.rb +74 -0
- data/spec/models/spree/taxonomy_spec.rb +18 -0
- data/spec/models/spree/tracker_spec.rb +21 -0
- data/spec/models/spree/transfer_item_spec.rb +264 -0
- data/spec/models/spree/unit_cancel_spec.rb +148 -0
- data/spec/models/spree/user_spec.rb +223 -0
- data/spec/models/spree/validations/db_maximum_length_validator_spec.rb +23 -0
- data/spec/models/spree/variant/scopes_spec.rb +55 -0
- data/spec/models/spree/variant_spec.rb +546 -0
- data/spec/models/spree/zone_spec.rb +305 -0
- data/spec/spec_helper.rb +78 -0
- data/spec/support/big_decimal.rb +5 -0
- data/spec/support/concerns/default_price.rb +34 -0
- data/spec/support/dummy_ability.rb +4 -0
- data/spec/support/test_gateway.rb +2 -0
- metadata +229 -3
- data/lib/spree/testing_support/rspec-activemodel-mocks_patch.rb +0 -8
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Spree
|
|
4
|
+
module PromotionHandler
|
|
5
|
+
describe Cart, :type => :model do
|
|
6
|
+
let(:line_item) { create(:line_item) }
|
|
7
|
+
let(:order) { line_item.order }
|
|
8
|
+
let(:promotion) { create(:promotion) }
|
|
9
|
+
let(:calculator) { Calculator::FlatPercentItemTotal.new(preferred_flat_percent: 10) }
|
|
10
|
+
|
|
11
|
+
subject { Cart.new(order, line_item) }
|
|
12
|
+
|
|
13
|
+
shared_context "creates the adjustment" do
|
|
14
|
+
it "creates the adjustment" do
|
|
15
|
+
expect {
|
|
16
|
+
subject.activate
|
|
17
|
+
}.to change { adjustable.adjustments.count }.by(1)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
shared_context "creates an order promotion" do
|
|
22
|
+
it "connects the promotion to the order" do
|
|
23
|
+
expect {
|
|
24
|
+
subject.activate
|
|
25
|
+
}.to change { order.promotions.reload.to_a }.from([]).to([promotion])
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
context "activates in LineItem level" do
|
|
30
|
+
let!(:action) { Promotion::Actions::CreateItemAdjustments.create(promotion: promotion, calculator: calculator) }
|
|
31
|
+
let(:adjustable) { line_item }
|
|
32
|
+
|
|
33
|
+
context "promotion with no rules" do
|
|
34
|
+
include_context "creates the adjustment"
|
|
35
|
+
include_context "creates an order promotion"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
context "promotion includes item involved" do
|
|
39
|
+
let!(:rule) { Promotion::Rules::Product.create(products: [line_item.product], promotion: promotion) }
|
|
40
|
+
|
|
41
|
+
include_context "creates the adjustment"
|
|
42
|
+
include_context "creates an order promotion"
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
context "promotion has item total rule" do
|
|
46
|
+
let(:shirt) { create(:product) }
|
|
47
|
+
let!(:rule) { Promotion::Rules::ItemTotal.create(preferred_operator: 'gt', preferred_amount: 50, promotion: promotion) }
|
|
48
|
+
|
|
49
|
+
before do
|
|
50
|
+
# Makes the order eligible for this promotion
|
|
51
|
+
order.item_total = 100
|
|
52
|
+
order.save
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
include_context "creates the adjustment"
|
|
56
|
+
include_context "creates an order promotion"
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
context "activates in Order level" do
|
|
61
|
+
let!(:action) { Promotion::Actions::CreateAdjustment.create(promotion: promotion, calculator: calculator) }
|
|
62
|
+
let(:adjustable) { order }
|
|
63
|
+
|
|
64
|
+
context "promotion with no rules" do
|
|
65
|
+
before do
|
|
66
|
+
# Gives the calculator something to discount
|
|
67
|
+
order.item_total = 10
|
|
68
|
+
order.save
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
include_context "creates the adjustment"
|
|
72
|
+
include_context "creates an order promotion"
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
context "promotion has item total rule" do
|
|
76
|
+
let(:shirt) { create(:product) }
|
|
77
|
+
let!(:rule) { Promotion::Rules::ItemTotal.create(preferred_operator: 'gt', preferred_amount: 50, promotion: promotion) }
|
|
78
|
+
|
|
79
|
+
before do
|
|
80
|
+
# Makes the order eligible for this promotion
|
|
81
|
+
order.item_total = 100
|
|
82
|
+
order.save
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
include_context "creates the adjustment"
|
|
86
|
+
include_context "creates an order promotion"
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
context "activates promotions associated with the order" do
|
|
91
|
+
let(:promotion) { create :promotion, :with_order_adjustment, code: 'promo' }
|
|
92
|
+
let(:promotion_code) { promotion.codes.first }
|
|
93
|
+
let(:adjustable) { order }
|
|
94
|
+
|
|
95
|
+
before do
|
|
96
|
+
Spree::OrderPromotion.create!(promotion: promotion, order: order, promotion_code: promotion_code)
|
|
97
|
+
order.update!
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
include_context "creates the adjustment"
|
|
101
|
+
|
|
102
|
+
it "records the promotion code in the adjustment" do
|
|
103
|
+
subject.activate
|
|
104
|
+
expect(adjustable.adjustments.map(&:promotion_code)).to eq [promotion_code]
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
it "checks if the promotion code is eligible" do
|
|
108
|
+
expect_any_instance_of(Spree::Promotion).to receive(:eligible?).at_least(2).times.with(anything, promotion_code: promotion_code).and_return(false)
|
|
109
|
+
subject.activate
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Spree
|
|
4
|
+
module PromotionHandler
|
|
5
|
+
describe Coupon, :type => :model do
|
|
6
|
+
let(:order) { double("Order", coupon_code: "10off").as_null_object }
|
|
7
|
+
|
|
8
|
+
subject { Coupon.new(order) }
|
|
9
|
+
|
|
10
|
+
def expect_order_connection(order:, promotion:, promotion_code:nil)
|
|
11
|
+
expect(order.promotions.to_a).to include(promotion)
|
|
12
|
+
expect(order.order_promotions.flat_map(&:promotion_code)).to include(promotion_code)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def expect_adjustment_creation(adjustable:, promotion:, promotion_code:nil)
|
|
16
|
+
expect(adjustable.adjustments.map(&:source).map(&:promotion)).to include(promotion)
|
|
17
|
+
expect(adjustable.adjustments.map(&:promotion_code)).to include(promotion_code)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
it "returns self in apply" do
|
|
22
|
+
expect(subject.apply).to be_a Coupon
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
context 'status messages' do
|
|
26
|
+
let(:coupon) { Coupon.new(order) }
|
|
27
|
+
|
|
28
|
+
describe "#set_success_code" do
|
|
29
|
+
let(:status) { :coupon_code_applied }
|
|
30
|
+
subject { coupon.set_success_code status }
|
|
31
|
+
|
|
32
|
+
it 'should have status_code' do
|
|
33
|
+
subject
|
|
34
|
+
expect(coupon.status_code).to eq(status)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it 'should have success message' do
|
|
38
|
+
subject
|
|
39
|
+
expect(coupon.success).to eq(Spree.t(status))
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
describe "#set_error_code" do
|
|
44
|
+
let(:status) { :coupon_code_not_found }
|
|
45
|
+
|
|
46
|
+
subject { coupon.set_error_code status }
|
|
47
|
+
|
|
48
|
+
it 'should have status_code' do
|
|
49
|
+
subject
|
|
50
|
+
expect(coupon.status_code).to eq(status)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
it 'should have error message' do
|
|
54
|
+
subject
|
|
55
|
+
expect(coupon.error).to eq(Spree.t(status))
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
context "coupon code promotion doesnt exist" do
|
|
61
|
+
before { create(:promotion) }
|
|
62
|
+
|
|
63
|
+
it "doesnt fetch any promotion" do
|
|
64
|
+
expect(subject.promotion).to be_blank
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
context "with no actions defined" do
|
|
68
|
+
before { create(:promotion, code: "10off") }
|
|
69
|
+
|
|
70
|
+
it "populates error message" do
|
|
71
|
+
subject.apply
|
|
72
|
+
expect(subject.error).to eq Spree.t(:coupon_code_not_found)
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
context "existing coupon code promotion" do
|
|
78
|
+
let!(:promotion) { promotion_code.promotion }
|
|
79
|
+
let(:promotion_code) { create(:promotion_code, value: '10off') }
|
|
80
|
+
let!(:action) { Promotion::Actions::CreateItemAdjustments.create(promotion: promotion, calculator: calculator) }
|
|
81
|
+
let(:calculator) { Calculator::FlatRate.new(preferred_amount: 10) }
|
|
82
|
+
|
|
83
|
+
it "fetches with given code" do
|
|
84
|
+
expect(subject.promotion).to eq promotion
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
context "with a per-item adjustment action" do
|
|
88
|
+
let(:order) { create(:order_with_line_items, :line_items_count => 3) }
|
|
89
|
+
|
|
90
|
+
context "right coupon given" do
|
|
91
|
+
context "with correct coupon code casing" do
|
|
92
|
+
before { allow(order).to receive_messages :coupon_code => "10off" }
|
|
93
|
+
|
|
94
|
+
it "successfully activates promo" do
|
|
95
|
+
expect(order.total).to eq(130)
|
|
96
|
+
subject.apply
|
|
97
|
+
expect(subject.success).to be_present
|
|
98
|
+
expect_order_connection(order: order, promotion: promotion, promotion_code: promotion_code)
|
|
99
|
+
order.line_items.each do |line_item|
|
|
100
|
+
expect_adjustment_creation(adjustable: line_item, promotion: promotion, promotion_code: promotion_code)
|
|
101
|
+
end
|
|
102
|
+
# Ensure that applying the adjustment actually affects the order's total!
|
|
103
|
+
expect(order.reload.total).to eq(100)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
it "coupon already applied to the order" do
|
|
107
|
+
subject.apply
|
|
108
|
+
expect(subject.success).to be_present
|
|
109
|
+
subject.apply
|
|
110
|
+
expect(subject.error).to eq Spree.t(:coupon_code_already_applied)
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Regression test for #4211
|
|
115
|
+
context "with incorrect coupon code casing" do
|
|
116
|
+
before { allow(order).to receive_messages :coupon_code => "10OFF" }
|
|
117
|
+
it "successfully activates promo" do
|
|
118
|
+
expect(order.total).to eq(130)
|
|
119
|
+
subject.apply
|
|
120
|
+
expect(subject.success).to be_present
|
|
121
|
+
expect_order_connection(order: order, promotion: promotion, promotion_code: promotion_code)
|
|
122
|
+
order.line_items.each do |line_item|
|
|
123
|
+
expect_adjustment_creation(adjustable: line_item, promotion: promotion, promotion_code: promotion_code)
|
|
124
|
+
end
|
|
125
|
+
# Ensure that applying the adjustment actually affects the order's total!
|
|
126
|
+
expect(order.reload.total).to eq(100)
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
context "coexists with a non coupon code promo" do
|
|
132
|
+
let!(:order) { Order.create }
|
|
133
|
+
|
|
134
|
+
before do
|
|
135
|
+
allow(order).to receive_messages :coupon_code => "10off"
|
|
136
|
+
calculator = Calculator::FlatRate.new(preferred_amount: 10)
|
|
137
|
+
general_promo = create(:promotion, name: "General Promo")
|
|
138
|
+
general_action = Promotion::Actions::CreateItemAdjustments.create(promotion: general_promo, calculator: calculator)
|
|
139
|
+
|
|
140
|
+
order.contents.add create(:variant)
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# regression spec for #4515
|
|
144
|
+
it "successfully activates promo" do
|
|
145
|
+
subject.apply
|
|
146
|
+
expect(subject).to be_successful
|
|
147
|
+
expect_order_connection(order: order, promotion: promotion, promotion_code: promotion_code)
|
|
148
|
+
order.line_items.each do |line_item|
|
|
149
|
+
expect_adjustment_creation(adjustable: line_item, promotion: promotion, promotion_code: promotion_code)
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
context "with a free-shipping adjustment action" do
|
|
156
|
+
let!(:action) { Promotion::Actions::FreeShipping.create!(promotion: promotion) }
|
|
157
|
+
context "right coupon code given" do
|
|
158
|
+
let(:order) { create(:order_with_line_items, :line_items_count => 3) }
|
|
159
|
+
|
|
160
|
+
before { allow(order).to receive_messages :coupon_code => "10off" }
|
|
161
|
+
|
|
162
|
+
it "successfully activates promo" do
|
|
163
|
+
expect(order.total).to eq(130)
|
|
164
|
+
subject.apply
|
|
165
|
+
expect(subject.success).to be_present
|
|
166
|
+
|
|
167
|
+
expect_order_connection(order: order, promotion: promotion, promotion_code: promotion_code)
|
|
168
|
+
order.shipments.each do |shipment|
|
|
169
|
+
expect_adjustment_creation(adjustable: shipment, promotion: promotion, promotion_code: promotion_code)
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
it "coupon already applied to the order" do
|
|
174
|
+
subject.apply
|
|
175
|
+
expect(subject.success).to be_present
|
|
176
|
+
subject.apply
|
|
177
|
+
expect(subject.error).to eq Spree.t(:coupon_code_already_applied)
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
context "with a whole-order adjustment action" do
|
|
183
|
+
let!(:action) { Promotion::Actions::CreateAdjustment.create(promotion: promotion, calculator: calculator) }
|
|
184
|
+
context "right coupon given" do
|
|
185
|
+
let(:order) { create(:order) }
|
|
186
|
+
let(:calculator) { Calculator::FlatRate.new(preferred_amount: 10) }
|
|
187
|
+
|
|
188
|
+
before do
|
|
189
|
+
allow(order).to receive_messages({
|
|
190
|
+
:coupon_code => "10off",
|
|
191
|
+
# These need to be here so that promotion adjustment "wins"
|
|
192
|
+
:item_total => 50,
|
|
193
|
+
:ship_total => 10
|
|
194
|
+
})
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
it "successfully activates promo" do
|
|
198
|
+
subject.apply
|
|
199
|
+
expect(subject.success).to be_present
|
|
200
|
+
expect(order.adjustments.count).to eq(1)
|
|
201
|
+
expect_order_connection(order: order, promotion: promotion, promotion_code: promotion_code)
|
|
202
|
+
expect_adjustment_creation(adjustable: order, promotion: promotion, promotion_code: promotion_code)
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
context "when the coupon is already applied to the order" do
|
|
206
|
+
before { subject.apply }
|
|
207
|
+
|
|
208
|
+
it "is not successful" do
|
|
209
|
+
subject.apply
|
|
210
|
+
expect(subject.successful?).to be false
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
it "returns a coupon has already been applied error" do
|
|
214
|
+
subject.apply
|
|
215
|
+
expect(subject.error).to eq Spree.t(:coupon_code_already_applied)
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
context "when the coupon fails to activate" do
|
|
220
|
+
before { allow_any_instance_of(Spree::Promotion).to receive(:activate).and_return false }
|
|
221
|
+
|
|
222
|
+
it "is not successful" do
|
|
223
|
+
subject.apply
|
|
224
|
+
expect(subject.successful?).to be false
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
it "returns a coupon failed to activate error" do
|
|
228
|
+
subject.apply
|
|
229
|
+
expect(subject.error).to eq Spree.t(:coupon_code_unknown_error)
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
context "when the promotion exceeds its usage limit" do
|
|
234
|
+
let!(:second_order) { FactoryGirl.create(:completed_order_with_promotion, promotion: promotion) }
|
|
235
|
+
|
|
236
|
+
before do
|
|
237
|
+
promotion.update!(usage_limit: 1)
|
|
238
|
+
Coupon.new(second_order).apply
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
it "is not successful" do
|
|
242
|
+
subject.apply
|
|
243
|
+
expect(subject.successful?).to be false
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
it "returns a coupon is at max usage error" do
|
|
247
|
+
subject.apply
|
|
248
|
+
expect(subject.error).to eq Spree.t(:coupon_code_max_usage)
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
context "for an order with taxable line items" do
|
|
255
|
+
before(:each) do
|
|
256
|
+
@country = create(:country)
|
|
257
|
+
@zone = create(:zone, :name => "Country Zone", :default_tax => true, :zone_members => [])
|
|
258
|
+
@zone.zone_members.create(:zoneable => @country)
|
|
259
|
+
@category = Spree::TaxCategory.create :name => "Taxable Foo"
|
|
260
|
+
@rate1 = Spree::TaxRate.create(
|
|
261
|
+
:amount => 0.10,
|
|
262
|
+
:calculator => Spree::Calculator::DefaultTax.create,
|
|
263
|
+
:tax_category => @category,
|
|
264
|
+
:zone => @zone
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
@order = Spree::Order.create!
|
|
268
|
+
allow(@order).to receive_messages :coupon_code => "10off"
|
|
269
|
+
end
|
|
270
|
+
context "and the product price is less than promo discount" do
|
|
271
|
+
before(:each) do
|
|
272
|
+
3.times do |i|
|
|
273
|
+
taxable = create(:product, :tax_category => @category, :price => 9.0)
|
|
274
|
+
@order.contents.add(taxable.master, 1)
|
|
275
|
+
end
|
|
276
|
+
end
|
|
277
|
+
it "successfully applies the promo" do
|
|
278
|
+
# 3 * (9 + 0.9)
|
|
279
|
+
expect(@order.total).to eq(29.7)
|
|
280
|
+
coupon = Coupon.new(@order)
|
|
281
|
+
coupon.apply
|
|
282
|
+
expect(coupon.success).to be_present
|
|
283
|
+
# 3 * ((9 - [9,10].min) + 0)
|
|
284
|
+
expect(@order.reload.total).to eq(0)
|
|
285
|
+
expect(@order.additional_tax_total).to eq(0)
|
|
286
|
+
end
|
|
287
|
+
end
|
|
288
|
+
context "and the product price is greater than promo discount" do
|
|
289
|
+
before(:each) do
|
|
290
|
+
3.times do |i|
|
|
291
|
+
taxable = create(:product, :tax_category => @category, :price => 11.0)
|
|
292
|
+
@order.contents.add(taxable.master, 2)
|
|
293
|
+
end
|
|
294
|
+
end
|
|
295
|
+
it "successfully applies the promo" do
|
|
296
|
+
# 3 * (22 + 2.2)
|
|
297
|
+
expect(@order.total.to_f).to eq(72.6)
|
|
298
|
+
coupon = Coupon.new(@order)
|
|
299
|
+
coupon.apply
|
|
300
|
+
expect(coupon.success).to be_present
|
|
301
|
+
# 3 * ( (22 - 10) + 1.2)
|
|
302
|
+
expect(@order.reload.total).to eq(39.6)
|
|
303
|
+
expect(@order.additional_tax_total).to eq(3.6)
|
|
304
|
+
end
|
|
305
|
+
end
|
|
306
|
+
context "and multiple quantity per line item" do
|
|
307
|
+
before(:each) do
|
|
308
|
+
twnty_off = create(:promotion, name: "promo", code: "20off")
|
|
309
|
+
twnty_off_calc = Calculator::FlatRate.new(preferred_amount: 20)
|
|
310
|
+
Promotion::Actions::CreateItemAdjustments.create(promotion: twnty_off,
|
|
311
|
+
calculator: twnty_off_calc)
|
|
312
|
+
|
|
313
|
+
allow(@order).to receive(:coupon_code).and_call_original
|
|
314
|
+
allow(@order).to receive_messages :coupon_code => "20off"
|
|
315
|
+
3.times do |i|
|
|
316
|
+
taxable = create(:product, :tax_category => @category, :price => 10.0)
|
|
317
|
+
@order.contents.add(taxable.master, 2)
|
|
318
|
+
end
|
|
319
|
+
end
|
|
320
|
+
it "successfully applies the promo" do
|
|
321
|
+
# 3 * ((2 * 10) + 2.0)
|
|
322
|
+
expect(@order.total.to_f).to eq(66)
|
|
323
|
+
coupon = Coupon.new(@order)
|
|
324
|
+
coupon.apply
|
|
325
|
+
expect(coupon.success).to be_present
|
|
326
|
+
# 0
|
|
327
|
+
expect(@order.reload.total).to eq(0)
|
|
328
|
+
expect(@order.additional_tax_total).to eq(0)
|
|
329
|
+
end
|
|
330
|
+
end
|
|
331
|
+
end
|
|
332
|
+
end
|
|
333
|
+
end
|
|
334
|
+
end
|
|
335
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Spree
|
|
4
|
+
module PromotionHandler
|
|
5
|
+
describe FreeShipping, type: :model do
|
|
6
|
+
let(:order) { create(:order) }
|
|
7
|
+
let(:shipment) { create(:shipment, order: order ) }
|
|
8
|
+
|
|
9
|
+
let(:promotion) { Promotion.create!(name: "Free Shipping") }
|
|
10
|
+
let(:calculator) { Calculator::FlatPercentItemTotal.new(preferred_flat_percent: 10) }
|
|
11
|
+
let!(:action) { Promotion::Actions::FreeShipping.create(promotion: promotion) }
|
|
12
|
+
|
|
13
|
+
subject { Spree::PromotionHandler::FreeShipping.new(order) }
|
|
14
|
+
|
|
15
|
+
context "activates in Shipment level" do
|
|
16
|
+
it "creates the adjustment" do
|
|
17
|
+
expect { subject.activate }.to change { shipment.adjustments.count }.by(1)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
context "if promo has a code" do
|
|
22
|
+
let!(:promotion_code) { create(:promotion_code, promotion: promotion) }
|
|
23
|
+
|
|
24
|
+
it "does adjust the shipment when applied to order" do
|
|
25
|
+
pending "broken by 2-2-dev merge"
|
|
26
|
+
order.order_promotions.create!(promotion: promotion, promotion_code: promotion_code)
|
|
27
|
+
|
|
28
|
+
expect { subject.activate }.to change { shipment.adjustments.count }
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "does not adjust the shipment when not applied to order" do
|
|
32
|
+
expect { subject.activate }.to_not change { shipment.adjustments.count }
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
context "if promo has a path" do
|
|
37
|
+
before do
|
|
38
|
+
promotion.update_column(:path, "path")
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "does not adjust the shipment" do
|
|
42
|
+
expect { subject.activate }.to_not change { shipment.adjustments.count }
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|