spree_core 3.2.1 → 3.2.2
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/lib/spree/core/version.rb +1 -1
- data/spree_core.gemspec +1 -1
- metadata +3 -206
- data/spec/fixtures/microdata.html +0 -22
- data/spec/fixtures/microdata_itemref.html +0 -15
- data/spec/fixtures/microdata_no_itemscope.html +0 -20
- data/spec/fixtures/thinking-cat.jpg +0 -0
- data/spec/helpers/base_helper_spec.rb +0 -200
- data/spec/helpers/products_helper_spec.rb +0 -289
- data/spec/lib/calculated_adjustments_spec.rb +0 -7
- data/spec/lib/i18n_spec.rb +0 -123
- data/spec/lib/search/base_spec.rb +0 -86
- data/spec/lib/spree/core/controller_helpers/auth_spec.rb +0 -103
- data/spec/lib/spree/core/controller_helpers/order_spec.rb +0 -110
- data/spec/lib/spree/core/controller_helpers/search_spec.rb +0 -17
- data/spec/lib/spree/core/controller_helpers/store_spec.rb +0 -72
- data/spec/lib/spree/core/controller_helpers/strong_parameters_spec.rb +0 -39
- data/spec/lib/spree/core/delegate_belongs_to_spec.rb +0 -22
- data/spec/lib/spree/core/importer/order_spec.rb +0 -605
- data/spec/lib/spree/core/number_generator_spec.rb +0 -175
- data/spec/lib/spree/core/token_generator_spec.rb +0 -24
- data/spec/lib/spree/core/validators/email_spec.rb +0 -53
- data/spec/lib/spree/core_spec.rb +0 -23
- data/spec/lib/spree/localized_number_spec.rb +0 -48
- data/spec/lib/spree/migrations_spec.rb +0 -36
- data/spec/lib/spree/money_spec.rb +0 -122
- data/spec/lib/tasks/exchanges_spec.rb +0 -136
- data/spec/mailers/order_mailer_spec.rb +0 -122
- data/spec/mailers/reimbursement_mailer_spec.rb +0 -47
- data/spec/mailers/shipment_mailer_spec.rb +0 -81
- data/spec/mailers/test_mailer_spec.rb +0 -38
- data/spec/models/option_type_prototype_spec.rb +0 -9
- data/spec/models/spree/ability_spec.rb +0 -251
- data/spec/models/spree/address_spec.rb +0 -402
- data/spec/models/spree/adjustable/adjuster/base_spec.rb +0 -10
- data/spec/models/spree/adjustable/adjuster/promotion_spec.rb +0 -211
- data/spec/models/spree/adjustable/adjuster/tax_spec.rb +0 -86
- data/spec/models/spree/adjustable/adjustments_updater_spec.rb +0 -26
- data/spec/models/spree/adjustment_spec.rb +0 -189
- data/spec/models/spree/app_configuration_spec.rb +0 -26
- data/spec/models/spree/asset_spec.rb +0 -28
- data/spec/models/spree/calculator/default_tax_spec.rb +0 -152
- data/spec/models/spree/calculator/flat_percent_item_total_spec.rb +0 -25
- data/spec/models/spree/calculator/flat_rate_spec.rb +0 -47
- data/spec/models/spree/calculator/flexi_rate_spec.rb +0 -41
- data/spec/models/spree/calculator/percent_on_line_item_spec.rb +0 -15
- data/spec/models/spree/calculator/price_sack_spec.rb +0 -30
- data/spec/models/spree/calculator/refunds/default_refund_amount_spec.rb +0 -47
- data/spec/models/spree/calculator/shipping.rb +0 -8
- data/spec/models/spree/calculator/shipping/flat_percent_item_total_spec.rb +0 -23
- data/spec/models/spree/calculator/shipping/flat_rate_spec.rb +0 -13
- data/spec/models/spree/calculator/shipping/flexi_rate_spec.rb +0 -52
- data/spec/models/spree/calculator/shipping/per_item_spec.rb +0 -20
- data/spec/models/spree/calculator/shipping/price_sack_spec.rb +0 -29
- data/spec/models/spree/calculator/tiered_flat_rate_spec.rb +0 -40
- data/spec/models/spree/calculator/tiered_percent_spec.rb +0 -51
- data/spec/models/spree/calculator_spec.rb +0 -69
- data/spec/models/spree/classification_spec.rb +0 -93
- data/spec/models/spree/concerns/display_money_spec.rb +0 -43
- data/spec/models/spree/concerns/user_methods_spec.rb +0 -82
- data/spec/models/spree/concerns/vat_price_calculation_spec.rb +0 -66
- data/spec/models/spree/country_spec.rb +0 -55
- data/spec/models/spree/credit_card_spec.rb +0 -328
- data/spec/models/spree/customer_return_spec.rb +0 -240
- data/spec/models/spree/exchange_spec.rb +0 -75
- data/spec/models/spree/gateway/bogus_simple.rb +0 -20
- data/spec/models/spree/gateway/bogus_spec.rb +0 -13
- data/spec/models/spree/gateway_spec.rb +0 -61
- data/spec/models/spree/image_spec.rb +0 -8
- data/spec/models/spree/inventory_unit_spec.rb +0 -256
- data/spec/models/spree/line_item_spec.rb +0 -346
- data/spec/models/spree/option_type_spec.rb +0 -14
- data/spec/models/spree/option_value_spec.rb +0 -18
- data/spec/models/spree/order/address_spec.rb +0 -50
- data/spec/models/spree/order/adjustments_spec.rb +0 -29
- data/spec/models/spree/order/callbacks_spec.rb +0 -42
- data/spec/models/spree/order/checkout_spec.rb +0 -770
- data/spec/models/spree/order/currency_updater_spec.rb +0 -32
- data/spec/models/spree/order/finalizing_spec.rb +0 -114
- data/spec/models/spree/order/helpers_spec.rb +0 -5
- data/spec/models/spree/order/payment_spec.rb +0 -214
- data/spec/models/spree/order/risk_assessment_spec.rb +0 -84
- data/spec/models/spree/order/shipments_spec.rb +0 -43
- data/spec/models/spree/order/state_machine_spec.rb +0 -212
- data/spec/models/spree/order/store_credit_spec.rb +0 -426
- data/spec/models/spree/order/tax_spec.rb +0 -84
- data/spec/models/spree/order/totals_spec.rb +0 -24
- data/spec/models/spree/order/updating_spec.rb +0 -18
- data/spec/models/spree/order/validations_spec.rb +0 -15
- data/spec/models/spree/order_contents_spec.rb +0 -297
- data/spec/models/spree/order_inventory_spec.rb +0 -239
- data/spec/models/spree/order_merger_spec.rb +0 -135
- data/spec/models/spree/order_spec.rb +0 -1046
- data/spec/models/spree/order_updater_spec.rb +0 -305
- data/spec/models/spree/payment/gateway_options_spec.rb +0 -127
- data/spec/models/spree/payment/store_credit_spec.rb +0 -60
- data/spec/models/spree/payment_method/store_credit_spec.rb +0 -291
- data/spec/models/spree/payment_method_spec.rb +0 -103
- data/spec/models/spree/payment_spec.rb +0 -919
- data/spec/models/spree/preference_spec.rb +0 -80
- data/spec/models/spree/preferences/configuration_spec.rb +0 -30
- data/spec/models/spree/preferences/preferable_spec.rb +0 -344
- data/spec/models/spree/preferences/scoped_store_spec.rb +0 -58
- data/spec/models/spree/preferences/store_spec.rb +0 -46
- data/spec/models/spree/price_spec.rb +0 -128
- data/spec/models/spree/product/scopes_spec.rb +0 -183
- data/spec/models/spree/product_duplicator_spec.rb +0 -103
- data/spec/models/spree/product_filter_spec.rb +0 -26
- data/spec/models/spree/product_option_type_spec.rb +0 -9
- data/spec/models/spree/product_promotion_rule_spec.rb +0 -9
- data/spec/models/spree/product_property_spec.rb +0 -26
- data/spec/models/spree/product_spec.rb +0 -629
- data/spec/models/spree/promotion/actions/create_adjustment_spec.rb +0 -113
- data/spec/models/spree/promotion/actions/create_item_adjustments_spec.rb +0 -148
- data/spec/models/spree/promotion/actions/create_line_items_spec.rb +0 -86
- data/spec/models/spree/promotion/actions/free_shipping_spec.rb +0 -36
- data/spec/models/spree/promotion/rules/country_spec.rb +0 -36
- data/spec/models/spree/promotion/rules/first_order_spec.rb +0 -75
- data/spec/models/spree/promotion/rules/item_total_spec.rb +0 -282
- data/spec/models/spree/promotion/rules/one_use_per_user_spec.rb +0 -42
- data/spec/models/spree/promotion/rules/option_value_spec.rb +0 -90
- data/spec/models/spree/promotion/rules/product_spec.rb +0 -143
- data/spec/models/spree/promotion/rules/taxon_spec.rb +0 -102
- data/spec/models/spree/promotion/rules/user_logged_in_spec.rb +0 -27
- data/spec/models/spree/promotion/rules/user_spec.rb +0 -45
- data/spec/models/spree/promotion_action_spec.rb +0 -10
- data/spec/models/spree/promotion_category_spec.rb +0 -17
- data/spec/models/spree/promotion_handler/cart_spec.rb +0 -102
- data/spec/models/spree/promotion_handler/coupon_spec.rb +0 -323
- data/spec/models/spree/promotion_handler/free_shipping_spec.rb +0 -48
- data/spec/models/spree/promotion_handler/page_spec.rb +0 -44
- data/spec/models/spree/promotion_rule_spec.rb +0 -29
- data/spec/models/spree/promotion_rule_taxon_spec.rb +0 -9
- data/spec/models/spree/promotion_rule_user_spec.rb +0 -9
- data/spec/models/spree/promotion_spec.rb +0 -679
- data/spec/models/spree/property_prototype_spec.rb +0 -9
- data/spec/models/spree/property_spec.rb +0 -5
- data/spec/models/spree/prototype_spec.rb +0 -5
- data/spec/models/spree/prototype_taxon_spec.rb +0 -9
- data/spec/models/spree/refund_reason_spec.rb +0 -20
- data/spec/models/spree/refund_spec.rb +0 -195
- data/spec/models/spree/reimbursement/credit_spec.rb +0 -36
- data/spec/models/spree/reimbursement/reimbursement_type_engine_spec.rb +0 -140
- data/spec/models/spree/reimbursement/reimbursement_type_validator_spec.rb +0 -83
- data/spec/models/spree/reimbursement_performer_spec.rb +0 -30
- data/spec/models/spree/reimbursement_spec.rb +0 -188
- data/spec/models/spree/reimbursement_tax_calculator_spec.rb +0 -63
- data/spec/models/spree/reimbursement_type/credit_spec.rb +0 -53
- data/spec/models/spree/reimbursement_type/exchange_spec.rb +0 -46
- data/spec/models/spree/reimbursement_type/original_payment_spec.rb +0 -55
- data/spec/models/spree/reimbursement_type/store_credit_spec.rb +0 -101
- data/spec/models/spree/return_authorization_reason_spec.rb +0 -7
- data/spec/models/spree/return_authorization_spec.rb +0 -230
- data/spec/models/spree/return_item/eligibility_validator/default_spec.rb +0 -77
- data/spec/models/spree/return_item/eligibility_validator/inventory_shipped_spec.rb +0 -58
- data/spec/models/spree/return_item/eligibility_validator/no_reimbursements_spec.rb +0 -61
- data/spec/models/spree/return_item/eligibility_validator/order_completed_spec.rb +0 -32
- data/spec/models/spree/return_item/eligibility_validator/rma_required_spec.rb +0 -29
- data/spec/models/spree/return_item/eligibility_validator/time_since_purchase_spec.rb +0 -35
- data/spec/models/spree/return_item/exchange_variant_eligibility/same_option_value_spec.rb +0 -65
- data/spec/models/spree/return_item/exchange_variant_eligibility/same_product_spec.rb +0 -43
- data/spec/models/spree/return_item_spec.rb +0 -731
- data/spec/models/spree/returns_calculator_spec.rb +0 -14
- data/spec/models/spree/role_spec.rb +0 -7
- data/spec/models/spree/shipment_spec.rb +0 -742
- data/spec/models/spree/shipping_calculator_spec.rb +0 -45
- data/spec/models/spree/shipping_category_spec.rb +0 -19
- data/spec/models/spree/shipping_method_spec.rb +0 -95
- data/spec/models/spree/shipping_rate_spec.rb +0 -140
- data/spec/models/spree/state_spec.rb +0 -29
- data/spec/models/spree/stock/availability_validator_spec.rb +0 -36
- data/spec/models/spree/stock/content_item_spec.rb +0 -31
- data/spec/models/spree/stock/coordinator_spec.rb +0 -61
- data/spec/models/spree/stock/differentiator_spec.rb +0 -39
- data/spec/models/spree/stock/estimator_spec.rb +0 -202
- data/spec/models/spree/stock/inventory_unit_builder_spec.rb +0 -38
- data/spec/models/spree/stock/package_spec.rb +0 -182
- data/spec/models/spree/stock/packer_spec.rb +0 -70
- data/spec/models/spree/stock/prioritizer_spec.rb +0 -125
- data/spec/models/spree/stock/quantifier_spec.rb +0 -126
- data/spec/models/spree/stock/splitter/backordered_spec.rb +0 -29
- data/spec/models/spree/stock/splitter/base_spec.rb +0 -21
- data/spec/models/spree/stock/splitter/shipping_category_spec.rb +0 -47
- data/spec/models/spree/stock/splitter/weight_spec.rb +0 -32
- data/spec/models/spree/stock_item_spec.rb +0 -432
- data/spec/models/spree/stock_location_spec.rb +0 -243
- data/spec/models/spree/stock_movement_spec.rb +0 -120
- data/spec/models/spree/stock_transfer_spec.rb +0 -50
- data/spec/models/spree/store_credit_event_spec.rb +0 -101
- data/spec/models/spree/store_credit_spec.rb +0 -786
- data/spec/models/spree/store_spec.rb +0 -78
- data/spec/models/spree/tax_category_spec.rb +0 -32
- data/spec/models/spree/tax_rate_spec.rb +0 -561
- data/spec/models/spree/taxon_spec.rb +0 -85
- data/spec/models/spree/taxonomy_spec.rb +0 -18
- data/spec/models/spree/tracker_spec.rb +0 -21
- data/spec/models/spree/user_spec.rb +0 -203
- data/spec/models/spree/variant_spec.rb +0 -818
- data/spec/models/spree/zone_member_spec.rb +0 -38
- data/spec/models/spree/zone_spec.rb +0 -472
- data/spec/spec_helper.rb +0 -79
- data/spec/support/big_decimal.rb +0 -5
- data/spec/support/concerns/adjustment_source.rb +0 -23
- data/spec/support/concerns/default_price.rb +0 -37
- data/spec/support/rake.rb +0 -13
- data/spec/support/test_gateway.rb +0 -2
|
@@ -1,48 +0,0 @@
|
|
|
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
|
-
before do
|
|
23
|
-
promotion.update_column(:code, "code")
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
it "does adjust the shipment when applied to order" do
|
|
27
|
-
order.promotions << promotion
|
|
28
|
-
|
|
29
|
-
expect { subject.activate }.to change { shipment.adjustments.count }
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
it "does not adjust the shipment when not applied to order" do
|
|
33
|
-
expect { subject.activate }.to_not change { shipment.adjustments.count }
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
context "if promo has a path" do
|
|
38
|
-
before do
|
|
39
|
-
promotion.update_column(:path, "path")
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
it "does not adjust the shipment" do
|
|
43
|
-
expect { subject.activate }.to_not change { shipment.adjustments.count }
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
end
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
module Spree
|
|
4
|
-
module PromotionHandler
|
|
5
|
-
describe Page, type: :model do
|
|
6
|
-
let(:order) { create(:order_with_line_items, line_items_count: 1) }
|
|
7
|
-
|
|
8
|
-
let(:promotion) { Promotion.create(name: "10% off", path: '10off') }
|
|
9
|
-
before do
|
|
10
|
-
calculator = Calculator::FlatPercentItemTotal.new(preferred_flat_percent: 10)
|
|
11
|
-
action = Promotion::Actions::CreateItemAdjustments.create(calculator: calculator)
|
|
12
|
-
promotion.actions << action
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
it "activates at the right path" do
|
|
16
|
-
expect(order.line_item_adjustments.count).to eq(0)
|
|
17
|
-
Spree::PromotionHandler::Page.new(order, '10off').activate
|
|
18
|
-
expect(order.line_item_adjustments.count).to eq(1)
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
context "when promotion is expired" do
|
|
22
|
-
before do
|
|
23
|
-
promotion.update_columns(
|
|
24
|
-
starts_at: 1.week.ago,
|
|
25
|
-
expires_at: 1.day.ago
|
|
26
|
-
)
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
it "is not activated" do
|
|
30
|
-
expect(order.line_item_adjustments.count).to eq(0)
|
|
31
|
-
Spree::PromotionHandler::Page.new(order, '10off').activate
|
|
32
|
-
expect(order.line_item_adjustments.count).to eq(0)
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
it "does not activate at the wrong path" do
|
|
37
|
-
expect(order.line_item_adjustments.count).to eq(0)
|
|
38
|
-
Spree::PromotionHandler::Page.new(order, 'wrongpath').activate
|
|
39
|
-
expect(order.line_item_adjustments.count).to eq(0)
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
module Spree
|
|
4
|
-
describe Spree::PromotionRule, type: :model do
|
|
5
|
-
|
|
6
|
-
class BadTestRule < Spree::PromotionRule; end
|
|
7
|
-
|
|
8
|
-
class TestRule < Spree::PromotionRule
|
|
9
|
-
def eligible?
|
|
10
|
-
true
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
it "should force developer to implement eligible? method" do
|
|
15
|
-
expect { BadTestRule.new.eligible? }.to raise_error(ArgumentError)
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
it "validates unique rules for a promotion" do
|
|
19
|
-
p1 = TestRule.new
|
|
20
|
-
p1.promotion_id = 1
|
|
21
|
-
p1.save
|
|
22
|
-
|
|
23
|
-
p2 = TestRule.new
|
|
24
|
-
p2.promotion_id = 1
|
|
25
|
-
expect(p2).not_to be_valid
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
end
|
|
29
|
-
end
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
describe Spree::PromotionRuleTaxon do
|
|
4
|
-
describe 'Validations' do
|
|
5
|
-
it { is_expected.to validate_presence_of(:promotion_rule) }
|
|
6
|
-
it { is_expected.to validate_presence_of(:taxon) }
|
|
7
|
-
it { is_expected.to validate_uniqueness_of(:promotion_rule_id).scoped_to(:taxon_id).allow_nil }
|
|
8
|
-
end
|
|
9
|
-
end
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
describe Spree::PromotionRuleUser do
|
|
4
|
-
describe 'Validations' do
|
|
5
|
-
it { is_expected.to validate_presence_of(:promotion_rule) }
|
|
6
|
-
it { is_expected.to validate_presence_of(:user) }
|
|
7
|
-
it { is_expected.to validate_uniqueness_of(:user_id).scoped_to(:promotion_rule_id).allow_nil }
|
|
8
|
-
end
|
|
9
|
-
end
|
|
@@ -1,679 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
describe Spree::Promotion, type: :model do
|
|
4
|
-
let(:promotion) { Spree::Promotion.new }
|
|
5
|
-
|
|
6
|
-
describe "validations" do
|
|
7
|
-
before :each do
|
|
8
|
-
@valid_promotion = Spree::Promotion.new name: "A promotion"
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
it "valid_promotion is valid" do
|
|
12
|
-
expect(@valid_promotion).to be_valid
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
it "validates usage limit" do
|
|
16
|
-
@valid_promotion.usage_limit = -1
|
|
17
|
-
expect(@valid_promotion).not_to be_valid
|
|
18
|
-
|
|
19
|
-
@valid_promotion.usage_limit = 100
|
|
20
|
-
expect(@valid_promotion).to be_valid
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
it "validates name" do
|
|
24
|
-
@valid_promotion.name = nil
|
|
25
|
-
expect(@valid_promotion).not_to be_valid
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
describe "expires_at_must_be_later_than_starts_at" do
|
|
29
|
-
before do
|
|
30
|
-
@valid_promotion.starts_at = Date.today
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
context "starts_at is a date earlier than expires_at" do
|
|
34
|
-
before { @valid_promotion.expires_at = 5.days.from_now }
|
|
35
|
-
|
|
36
|
-
it "is valid" do
|
|
37
|
-
expect(@valid_promotion).to be_valid
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
context "starts_at is a date earlier than expires_at" do
|
|
42
|
-
before { @valid_promotion.expires_at = 5.days.ago }
|
|
43
|
-
|
|
44
|
-
context "is not valid" do
|
|
45
|
-
before { @valid_promotion.valid? }
|
|
46
|
-
it { expect(@valid_promotion).not_to be_valid }
|
|
47
|
-
it { expect(@valid_promotion.errors[:expires_at]).to include(I18n.t(:invalid_date_range, scope: 'activerecord.errors.models.spree/promotion.attributes.expires_at')) }
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
context "starts_at and expires_at are nil" do
|
|
52
|
-
before do
|
|
53
|
-
@valid_promotion.expires_at = nil
|
|
54
|
-
@valid_promotion.starts_at = nil
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
it "is valid" do
|
|
58
|
-
expect(@valid_promotion).to be_valid
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
describe 'scopes' do
|
|
65
|
-
describe '.coupons' do
|
|
66
|
-
let!(:promotion_without_code) { Spree::Promotion.create! name: 'test', code: '' }
|
|
67
|
-
let!(:promotion_with_code) { Spree::Promotion.create! name: 'test1', code: 'code' }
|
|
68
|
-
|
|
69
|
-
subject { Spree::Promotion.coupons }
|
|
70
|
-
|
|
71
|
-
it 'is expected to not include promotion without code' do
|
|
72
|
-
is_expected.to_not include(promotion_without_code)
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
it 'is expected to include promotion with code' do
|
|
76
|
-
is_expected.to include(promotion_with_code)
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
describe '.applied' do
|
|
81
|
-
let!(:promotion_not_applied) { Spree::Promotion.create! name: 'test', code: '' }
|
|
82
|
-
let(:order) { create(:order) }
|
|
83
|
-
let!(:promotion_applied) do
|
|
84
|
-
promotion = Spree::Promotion.create!(name: 'test1', code: '')
|
|
85
|
-
promotion.orders << order
|
|
86
|
-
promotion
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
subject { Spree::Promotion.applied }
|
|
90
|
-
|
|
91
|
-
it 'is expected to not include promotion not applied' do
|
|
92
|
-
is_expected.to_not include(promotion_not_applied)
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
it 'is expected to include promotion applied' do
|
|
96
|
-
is_expected.to include(promotion_applied)
|
|
97
|
-
end
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
describe '.advertised' do
|
|
101
|
-
let!(:promotion_not_advertised) { Spree::Promotion.create! name: 'test', advertise: false }
|
|
102
|
-
let!(:promotion_advertised) { Spree::Promotion.create! name: 'test1', advertise: true }
|
|
103
|
-
|
|
104
|
-
subject { Spree::Promotion.advertised }
|
|
105
|
-
|
|
106
|
-
it 'is expected to not include promotion not advertised' do
|
|
107
|
-
is_expected.to_not include(promotion_not_advertised)
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
it 'is expected to include promotion advertised' do
|
|
111
|
-
is_expected.to include(promotion_advertised)
|
|
112
|
-
end
|
|
113
|
-
end
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
describe "#destroy" do
|
|
117
|
-
let(:promotion) { Spree::Promotion.create(name: "delete me") }
|
|
118
|
-
|
|
119
|
-
before(:each) do
|
|
120
|
-
promotion.actions << Spree::Promotion::Actions::CreateAdjustment.new
|
|
121
|
-
promotion.rules << Spree::Promotion::Rules::FirstOrder.new
|
|
122
|
-
promotion.save!
|
|
123
|
-
promotion.destroy
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
it "should delete actions" do
|
|
127
|
-
expect(Spree::PromotionAction.count).to eq(0)
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
it "should delete rules" do
|
|
131
|
-
expect(Spree::PromotionRule.count).to eq(0)
|
|
132
|
-
end
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
describe "#save" do
|
|
136
|
-
let(:promotion) { Spree::Promotion.create(name: "delete me") }
|
|
137
|
-
|
|
138
|
-
before(:each) do
|
|
139
|
-
promotion.actions << Spree::Promotion::Actions::CreateAdjustment.new
|
|
140
|
-
promotion.rules << Spree::Promotion::Rules::FirstOrder.new
|
|
141
|
-
promotion.save!
|
|
142
|
-
end
|
|
143
|
-
|
|
144
|
-
it "should deeply autosave records and preferences" do
|
|
145
|
-
promotion.actions[0].calculator.preferred_flat_percent = 10
|
|
146
|
-
promotion.save!
|
|
147
|
-
expect(Spree::Calculator.first.preferred_flat_percent).to eq(10)
|
|
148
|
-
end
|
|
149
|
-
end
|
|
150
|
-
|
|
151
|
-
describe "#activate" do
|
|
152
|
-
before do
|
|
153
|
-
@action1 = Spree::Promotion::Actions::CreateAdjustment.create!
|
|
154
|
-
@action2 = Spree::Promotion::Actions::CreateAdjustment.create!
|
|
155
|
-
allow(@action1).to receive_messages perform: true
|
|
156
|
-
allow(@action2).to receive_messages perform: true
|
|
157
|
-
|
|
158
|
-
promotion.promotion_actions = [@action1, @action2]
|
|
159
|
-
promotion.created_at = 2.days.ago
|
|
160
|
-
|
|
161
|
-
@user = stub_model(Spree::LegacyUser, email: "spree@example.com")
|
|
162
|
-
@order = Spree::Order.create user: @user
|
|
163
|
-
@payload = { order: @order, user: @user }
|
|
164
|
-
end
|
|
165
|
-
|
|
166
|
-
it "should check path if present" do
|
|
167
|
-
promotion.path = 'content/cvv'
|
|
168
|
-
@payload[:path] = 'content/cvv'
|
|
169
|
-
expect(@action1).to receive(:perform).with(@payload)
|
|
170
|
-
expect(@action2).to receive(:perform).with(@payload)
|
|
171
|
-
promotion.activate(@payload)
|
|
172
|
-
end
|
|
173
|
-
|
|
174
|
-
it "does not perform actions against an order in a finalized state" do
|
|
175
|
-
expect(@action1).not_to receive(:perform).with(@payload)
|
|
176
|
-
|
|
177
|
-
@order.state = 'complete'
|
|
178
|
-
promotion.activate(@payload)
|
|
179
|
-
|
|
180
|
-
@order.state = 'awaiting_return'
|
|
181
|
-
promotion.activate(@payload)
|
|
182
|
-
|
|
183
|
-
@order.state = 'returned'
|
|
184
|
-
promotion.activate(@payload)
|
|
185
|
-
end
|
|
186
|
-
|
|
187
|
-
it "does activate if newer then order" do
|
|
188
|
-
expect(@action1).to receive(:perform).with(@payload)
|
|
189
|
-
promotion.created_at = DateTime.current + 2
|
|
190
|
-
expect(promotion.activate(@payload)).to be true
|
|
191
|
-
end
|
|
192
|
-
|
|
193
|
-
context "keeps track of the orders" do
|
|
194
|
-
context "when activated" do
|
|
195
|
-
it "assigns the order" do
|
|
196
|
-
expect(promotion.orders).to be_empty
|
|
197
|
-
expect(promotion.activate(@payload)).to be true
|
|
198
|
-
expect(promotion.orders.first).to eql @order
|
|
199
|
-
end
|
|
200
|
-
end
|
|
201
|
-
context "when not activated" do
|
|
202
|
-
it "will not assign the order" do
|
|
203
|
-
@order.state = 'complete'
|
|
204
|
-
expect(promotion.orders).to be_empty
|
|
205
|
-
expect(promotion.activate(@payload)).to be_falsey
|
|
206
|
-
expect(promotion.orders).to be_empty
|
|
207
|
-
end
|
|
208
|
-
end
|
|
209
|
-
|
|
210
|
-
end
|
|
211
|
-
|
|
212
|
-
end
|
|
213
|
-
|
|
214
|
-
context "#usage_limit_exceeded" do
|
|
215
|
-
let(:promotable) { double('Promotable') }
|
|
216
|
-
it "should not have its usage limit exceeded with no usage limit" do
|
|
217
|
-
promotion.usage_limit = 0
|
|
218
|
-
expect(promotion.usage_limit_exceeded?(promotable)).to be false
|
|
219
|
-
end
|
|
220
|
-
|
|
221
|
-
it "should have its usage limit exceeded" do
|
|
222
|
-
promotion.usage_limit = 2
|
|
223
|
-
allow(promotion).to receive_messages(adjusted_credits_count: 2)
|
|
224
|
-
expect(promotion.usage_limit_exceeded?(promotable)).to be true
|
|
225
|
-
|
|
226
|
-
allow(promotion).to receive_messages(adjusted_credits_count: 3)
|
|
227
|
-
expect(promotion.usage_limit_exceeded?(promotable)).to be true
|
|
228
|
-
end
|
|
229
|
-
end
|
|
230
|
-
|
|
231
|
-
context "#expired" do
|
|
232
|
-
it "should not be exipired" do
|
|
233
|
-
expect(promotion).not_to be_expired
|
|
234
|
-
end
|
|
235
|
-
|
|
236
|
-
it "should be expired if it hasn't started yet" do
|
|
237
|
-
promotion.starts_at = Time.current + 1.day
|
|
238
|
-
expect(promotion).to be_expired
|
|
239
|
-
end
|
|
240
|
-
|
|
241
|
-
it "should be expired if it has already ended" do
|
|
242
|
-
promotion.expires_at = Time.current - 1.day
|
|
243
|
-
expect(promotion).to be_expired
|
|
244
|
-
end
|
|
245
|
-
|
|
246
|
-
it "should not be expired if it has started already" do
|
|
247
|
-
promotion.starts_at = Time.current - 1.day
|
|
248
|
-
expect(promotion).not_to be_expired
|
|
249
|
-
end
|
|
250
|
-
|
|
251
|
-
it "should not be expired if it has not ended yet" do
|
|
252
|
-
promotion.expires_at = Time.current + 1.day
|
|
253
|
-
expect(promotion).not_to be_expired
|
|
254
|
-
end
|
|
255
|
-
|
|
256
|
-
it "should not be expired if current time is within starts_at and expires_at range" do
|
|
257
|
-
promotion.starts_at = Time.current - 1.day
|
|
258
|
-
promotion.expires_at = Time.current + 1.day
|
|
259
|
-
expect(promotion).not_to be_expired
|
|
260
|
-
end
|
|
261
|
-
|
|
262
|
-
it "should not be expired if usage limit is not exceeded" do
|
|
263
|
-
promotion.usage_limit = 2
|
|
264
|
-
allow(promotion).to receive_messages(credits_count: 1)
|
|
265
|
-
expect(promotion).not_to be_expired
|
|
266
|
-
end
|
|
267
|
-
end
|
|
268
|
-
|
|
269
|
-
context "#credits_count" do
|
|
270
|
-
let!(:promotion) do
|
|
271
|
-
promotion = Spree::Promotion.new
|
|
272
|
-
promotion.name = "Foo"
|
|
273
|
-
promotion.code = "XXX"
|
|
274
|
-
calculator = Spree::Calculator::FlatRate.new
|
|
275
|
-
promotion.tap(&:save)
|
|
276
|
-
end
|
|
277
|
-
|
|
278
|
-
let!(:action) do
|
|
279
|
-
calculator = Spree::Calculator::FlatRate.new
|
|
280
|
-
action_params = { promotion: promotion, calculator: calculator }
|
|
281
|
-
action = Spree::Promotion::Actions::CreateAdjustment.create(action_params)
|
|
282
|
-
promotion.actions << action
|
|
283
|
-
action
|
|
284
|
-
end
|
|
285
|
-
|
|
286
|
-
let!(:adjustment) do
|
|
287
|
-
order = create(:order)
|
|
288
|
-
Spree::Adjustment.create!(
|
|
289
|
-
order: order,
|
|
290
|
-
adjustable: order,
|
|
291
|
-
source: action,
|
|
292
|
-
amount: 10,
|
|
293
|
-
label: 'Promotional adjustment'
|
|
294
|
-
)
|
|
295
|
-
end
|
|
296
|
-
|
|
297
|
-
it "counts eligible adjustments" do
|
|
298
|
-
adjustment.update_column(:eligible, true)
|
|
299
|
-
expect(promotion.credits_count).to eq(1)
|
|
300
|
-
end
|
|
301
|
-
|
|
302
|
-
# Regression test for #4112
|
|
303
|
-
it "does not count ineligible adjustments" do
|
|
304
|
-
adjustment.update_column(:eligible, false)
|
|
305
|
-
expect(promotion.credits_count).to eq(0)
|
|
306
|
-
end
|
|
307
|
-
end
|
|
308
|
-
|
|
309
|
-
context "#adjusted_credits_count" do
|
|
310
|
-
let(:order) { create :order }
|
|
311
|
-
let(:line_item) { create :line_item, order: order }
|
|
312
|
-
let(:promotion) { Spree::Promotion.create name: "promo", code: "10off" }
|
|
313
|
-
let(:order_action) {
|
|
314
|
-
action = Spree::Promotion::Actions::CreateAdjustment.create(calculator: Spree::Calculator::FlatPercentItemTotal.new)
|
|
315
|
-
promotion.actions << action
|
|
316
|
-
action
|
|
317
|
-
}
|
|
318
|
-
let(:item_action) {
|
|
319
|
-
action = Spree::Promotion::Actions::CreateItemAdjustments.create(calculator: Spree::Calculator::FlatPercentItemTotal.new)
|
|
320
|
-
promotion.actions << action
|
|
321
|
-
action
|
|
322
|
-
}
|
|
323
|
-
let(:order_adjustment) do
|
|
324
|
-
Spree::Adjustment.create!(
|
|
325
|
-
source: order_action,
|
|
326
|
-
amount: 10,
|
|
327
|
-
adjustable: order,
|
|
328
|
-
order: order,
|
|
329
|
-
label: "Promotional adjustment"
|
|
330
|
-
)
|
|
331
|
-
end
|
|
332
|
-
let(:item_adjustment) do
|
|
333
|
-
Spree::Adjustment.create!(
|
|
334
|
-
source: item_action,
|
|
335
|
-
amount: 10,
|
|
336
|
-
adjustable: line_item,
|
|
337
|
-
order: order,
|
|
338
|
-
label: "Promotional adjustment"
|
|
339
|
-
)
|
|
340
|
-
end
|
|
341
|
-
|
|
342
|
-
it "counts order level adjustments" do
|
|
343
|
-
expect(order_adjustment.adjustable).to eq(order)
|
|
344
|
-
expect(promotion.credits_count).to eq(1)
|
|
345
|
-
expect(promotion.adjusted_credits_count(order)).to eq(0)
|
|
346
|
-
end
|
|
347
|
-
|
|
348
|
-
it "counts item level adjustments" do
|
|
349
|
-
expect(item_adjustment.adjustable).to eq(line_item)
|
|
350
|
-
expect(promotion.credits_count).to eq(1)
|
|
351
|
-
expect(promotion.adjusted_credits_count(order)).to eq(0)
|
|
352
|
-
end
|
|
353
|
-
end
|
|
354
|
-
|
|
355
|
-
context "#products" do
|
|
356
|
-
let(:product) { create(:product) }
|
|
357
|
-
let(:promotion) { create(:promotion) }
|
|
358
|
-
|
|
359
|
-
context "when it has product rules with products associated" do
|
|
360
|
-
let(:promotion_rule) { create(:promotion_rule, promotion: promotion, type: 'Spree::Promotion::Rules::Product') }
|
|
361
|
-
|
|
362
|
-
before do
|
|
363
|
-
promotion.promotion_rules << promotion_rule
|
|
364
|
-
product.product_promotion_rules.create(promotion_rule_id: promotion_rule.id)
|
|
365
|
-
end
|
|
366
|
-
|
|
367
|
-
it "should have products" do
|
|
368
|
-
expect(promotion.reload.products.size).to eq(1)
|
|
369
|
-
end
|
|
370
|
-
end
|
|
371
|
-
|
|
372
|
-
context "when there's no product rule associated" do
|
|
373
|
-
it "should not have products but still return an empty array" do
|
|
374
|
-
expect(promotion.products).to be_blank
|
|
375
|
-
end
|
|
376
|
-
end
|
|
377
|
-
end
|
|
378
|
-
|
|
379
|
-
context "#eligible?" do
|
|
380
|
-
let(:promotable) { create :order }
|
|
381
|
-
subject { promotion.eligible?(promotable) }
|
|
382
|
-
context "when promotion is expired" do
|
|
383
|
-
before { promotion.expires_at = Time.current - 10.days }
|
|
384
|
-
it { is_expected.to be false }
|
|
385
|
-
end
|
|
386
|
-
context "when promotable is a Spree::LineItem" do
|
|
387
|
-
let(:promotable) { create :line_item }
|
|
388
|
-
let(:product) { promotable.product }
|
|
389
|
-
before do
|
|
390
|
-
product.promotionable = promotionable
|
|
391
|
-
end
|
|
392
|
-
context "and product is promotionable" do
|
|
393
|
-
let(:promotionable) { true }
|
|
394
|
-
it { is_expected.to be true }
|
|
395
|
-
end
|
|
396
|
-
context "and product is not promotionable" do
|
|
397
|
-
let(:promotionable) { false }
|
|
398
|
-
it { is_expected.to be false }
|
|
399
|
-
end
|
|
400
|
-
end
|
|
401
|
-
context "when promotable is a Spree::Order" do
|
|
402
|
-
let(:promotable) { create :order }
|
|
403
|
-
context "and it is empty" do
|
|
404
|
-
it { is_expected.to be true }
|
|
405
|
-
end
|
|
406
|
-
context "and it contains items" do
|
|
407
|
-
let!(:line_item) { create(:line_item, order: promotable) }
|
|
408
|
-
context "and the items are all non-promotionable" do
|
|
409
|
-
before do
|
|
410
|
-
line_item.product.update_column(:promotionable, false)
|
|
411
|
-
end
|
|
412
|
-
it { is_expected.to be false }
|
|
413
|
-
end
|
|
414
|
-
context "and at least one item is promotionable" do
|
|
415
|
-
it { is_expected.to be true }
|
|
416
|
-
end
|
|
417
|
-
end
|
|
418
|
-
end
|
|
419
|
-
end
|
|
420
|
-
|
|
421
|
-
context "#eligible_rules" do
|
|
422
|
-
let(:promotable) { double('Promotable') }
|
|
423
|
-
it "true if there are no rules" do
|
|
424
|
-
expect(promotion.eligible_rules(promotable)).to eq []
|
|
425
|
-
end
|
|
426
|
-
|
|
427
|
-
it "true if there are no applicable rules" do
|
|
428
|
-
promotion.promotion_rules = [stub_model(Spree::PromotionRule, eligible?: true, applicable?: false)]
|
|
429
|
-
allow(promotion.promotion_rules).to receive(:for).and_return([])
|
|
430
|
-
expect(promotion.eligible_rules(promotable)).to eq []
|
|
431
|
-
end
|
|
432
|
-
|
|
433
|
-
context "with 'all' match policy" do
|
|
434
|
-
let(:promo1) { Spree::PromotionRule.create! }
|
|
435
|
-
let(:promo2) { Spree::PromotionRule.create! }
|
|
436
|
-
|
|
437
|
-
before { promotion.match_policy = 'all' }
|
|
438
|
-
|
|
439
|
-
context "when all rules are eligible" do
|
|
440
|
-
before do
|
|
441
|
-
allow(promo1).to receive_messages(eligible?: true, applicable?: true)
|
|
442
|
-
allow(promo2).to receive_messages(eligible?: true, applicable?: true)
|
|
443
|
-
|
|
444
|
-
promotion.promotion_rules = [promo1, promo2]
|
|
445
|
-
allow(promotion.promotion_rules).to receive(:for).and_return(promotion.promotion_rules)
|
|
446
|
-
end
|
|
447
|
-
it "returns the eligible rules" do
|
|
448
|
-
expect(promotion.eligible_rules(promotable)).to eq [promo1, promo2]
|
|
449
|
-
end
|
|
450
|
-
it "does set anything to eligiblity errors" do
|
|
451
|
-
promotion.eligible_rules(promotable)
|
|
452
|
-
expect(promotion.eligibility_errors).to be_nil
|
|
453
|
-
end
|
|
454
|
-
end
|
|
455
|
-
|
|
456
|
-
context "when any of the rules is not eligible" do
|
|
457
|
-
let(:errors) { double ActiveModel::Errors, empty?: false }
|
|
458
|
-
before do
|
|
459
|
-
allow(promo1).to receive_messages(eligible?: true, applicable?: true, eligibility_errors: nil)
|
|
460
|
-
allow(promo2).to receive_messages(eligible?: false, applicable?: true, eligibility_errors: errors)
|
|
461
|
-
|
|
462
|
-
promotion.promotion_rules = [promo1, promo2]
|
|
463
|
-
allow(promotion.promotion_rules).to receive(:for).and_return(promotion.promotion_rules)
|
|
464
|
-
end
|
|
465
|
-
it "returns nil" do
|
|
466
|
-
expect(promotion.eligible_rules(promotable)).to be_nil
|
|
467
|
-
end
|
|
468
|
-
it "sets eligibility errors to the first non-nil one" do
|
|
469
|
-
promotion.eligible_rules(promotable)
|
|
470
|
-
expect(promotion.eligibility_errors).to eq errors
|
|
471
|
-
end
|
|
472
|
-
end
|
|
473
|
-
end
|
|
474
|
-
|
|
475
|
-
context "with 'any' match policy" do
|
|
476
|
-
let(:promotion) { Spree::Promotion.create(name: "Promo", match_policy: 'any') }
|
|
477
|
-
let(:promotable) { double('Promotable') }
|
|
478
|
-
|
|
479
|
-
it "should have eligible rules if any of the rules are eligible" do
|
|
480
|
-
allow_any_instance_of(Spree::PromotionRule).to receive_messages(applicable?: true)
|
|
481
|
-
true_rule = Spree::PromotionRule.create(promotion: promotion)
|
|
482
|
-
allow(true_rule).to receive_messages(eligible?: true)
|
|
483
|
-
allow(promotion).to receive_messages(rules: [true_rule])
|
|
484
|
-
allow(promotion).to receive_message_chain(:rules, :for).and_return([true_rule])
|
|
485
|
-
expect(promotion.eligible_rules(promotable)).to eq [true_rule]
|
|
486
|
-
end
|
|
487
|
-
|
|
488
|
-
context "when none of the rules are eligible" do
|
|
489
|
-
let(:promo) { Spree::PromotionRule.create! }
|
|
490
|
-
let(:errors) { double ActiveModel::Errors, empty?: false }
|
|
491
|
-
before do
|
|
492
|
-
allow(promo).to receive_messages(eligible?: false, applicable?: true, eligibility_errors: errors)
|
|
493
|
-
|
|
494
|
-
promotion.promotion_rules = [promo]
|
|
495
|
-
allow(promotion.promotion_rules).to receive(:for).and_return(promotion.promotion_rules)
|
|
496
|
-
end
|
|
497
|
-
it "returns nil" do
|
|
498
|
-
expect(promotion.eligible_rules(promotable)).to be_nil
|
|
499
|
-
end
|
|
500
|
-
it "sets eligibility errors to the first non-nil one" do
|
|
501
|
-
promotion.eligible_rules(promotable)
|
|
502
|
-
expect(promotion.eligibility_errors).to eq errors
|
|
503
|
-
end
|
|
504
|
-
end
|
|
505
|
-
end
|
|
506
|
-
end
|
|
507
|
-
|
|
508
|
-
describe '#line_item_actionable?' do
|
|
509
|
-
let(:order) { double Spree::Order }
|
|
510
|
-
let(:line_item) { double Spree::LineItem}
|
|
511
|
-
let(:true_rule) { double Spree::PromotionRule, eligible?: true, applicable?: true, actionable?: true }
|
|
512
|
-
let(:false_rule) { double Spree::PromotionRule, eligible?: true, applicable?: true, actionable?: false }
|
|
513
|
-
let(:rules) { [] }
|
|
514
|
-
|
|
515
|
-
before do
|
|
516
|
-
allow(promotion).to receive(:rules) { rules }
|
|
517
|
-
allow(rules).to receive(:for) { rules }
|
|
518
|
-
end
|
|
519
|
-
|
|
520
|
-
subject { promotion.line_item_actionable? order, line_item }
|
|
521
|
-
|
|
522
|
-
context 'when the order is eligible for promotion' do
|
|
523
|
-
context 'when there are no rules' do
|
|
524
|
-
it { is_expected.to be }
|
|
525
|
-
end
|
|
526
|
-
|
|
527
|
-
context 'when there are rules' do
|
|
528
|
-
context 'when the match policy is all' do
|
|
529
|
-
before { promotion.match_policy = 'all' }
|
|
530
|
-
|
|
531
|
-
context 'when all rules allow action on the line item' do
|
|
532
|
-
let(:rules) { [true_rule] }
|
|
533
|
-
it { is_expected.to be}
|
|
534
|
-
end
|
|
535
|
-
|
|
536
|
-
context 'when at least one rule does not allow action on the line item' do
|
|
537
|
-
let(:rules) { [true_rule, false_rule] }
|
|
538
|
-
it { is_expected.not_to be}
|
|
539
|
-
end
|
|
540
|
-
end
|
|
541
|
-
|
|
542
|
-
context 'when the match policy is any' do
|
|
543
|
-
before { promotion.match_policy = 'any' }
|
|
544
|
-
|
|
545
|
-
context 'when at least one rule allows action on the line item' do
|
|
546
|
-
let(:rules) { [true_rule, false_rule] }
|
|
547
|
-
it { is_expected.to be }
|
|
548
|
-
end
|
|
549
|
-
|
|
550
|
-
context 'when no rules allow action on the line item' do
|
|
551
|
-
let(:rules) { [false_rule] }
|
|
552
|
-
it { is_expected.not_to be}
|
|
553
|
-
end
|
|
554
|
-
end
|
|
555
|
-
end
|
|
556
|
-
end
|
|
557
|
-
|
|
558
|
-
context 'when the order is not eligible for the promotion' do
|
|
559
|
-
before { promotion.starts_at = Time.current + 2.days }
|
|
560
|
-
it { is_expected.not_to be }
|
|
561
|
-
end
|
|
562
|
-
end
|
|
563
|
-
|
|
564
|
-
# regression for #4059
|
|
565
|
-
# admin form posts the code and path as empty string
|
|
566
|
-
describe "normalize blank values for code & path" do
|
|
567
|
-
it "will save blank value as nil value instead" do
|
|
568
|
-
promotion = Spree::Promotion.create(name: "A promotion", code: "", path: "")
|
|
569
|
-
expect(promotion.code).to be_nil
|
|
570
|
-
expect(promotion.path).to be_nil
|
|
571
|
-
end
|
|
572
|
-
end
|
|
573
|
-
|
|
574
|
-
# Regression test for #4081
|
|
575
|
-
describe "#with_coupon_code" do
|
|
576
|
-
context "and code stored in uppercase" do
|
|
577
|
-
let!(:promotion) { create(:promotion, :with_order_adjustment, code: "MY-COUPON-123") }
|
|
578
|
-
it "finds the code with lowercase" do
|
|
579
|
-
expect(Spree::Promotion.with_coupon_code("my-coupon-123")).to eql promotion
|
|
580
|
-
end
|
|
581
|
-
end
|
|
582
|
-
|
|
583
|
-
context "and there are multiple coupons with the same code" do
|
|
584
|
-
context "and only one has any actions" do
|
|
585
|
-
let!(:promotion_without_actions) { create(:promotion, code: "MY-COUPON-123").actions.clear }
|
|
586
|
-
let!(:promotion) { create(:promotion, :with_order_adjustment, code: "MY-COUPON-123") }
|
|
587
|
-
|
|
588
|
-
it "then returns the one with an action" do
|
|
589
|
-
expect(Spree::Promotion.with_coupon_code("MY-COUPON-123").actions.exists?).to be
|
|
590
|
-
end
|
|
591
|
-
end
|
|
592
|
-
|
|
593
|
-
context "and all of them has actions" do
|
|
594
|
-
let!(:first_promotion) { create(:promotion, :with_order_adjustment, code: "MY-COUPON-123") }
|
|
595
|
-
let!(:second_promotion) { create(:promotion, :with_order_adjustment, code: "MY-COUPON-123") }
|
|
596
|
-
|
|
597
|
-
it "then returns the first one with an action" do
|
|
598
|
-
expect(Spree::Promotion.with_coupon_code("MY-COUPON-123").id).to eq(first_promotion.id)
|
|
599
|
-
end
|
|
600
|
-
end
|
|
601
|
-
end
|
|
602
|
-
end
|
|
603
|
-
|
|
604
|
-
describe '#used_by?' do
|
|
605
|
-
subject { promotion.used_by? user, [excluded_order] }
|
|
606
|
-
|
|
607
|
-
let(:promotion) { create :promotion, :with_order_adjustment }
|
|
608
|
-
let(:user) { create :user }
|
|
609
|
-
let(:order) { create :order_with_line_items, user: user }
|
|
610
|
-
let(:excluded_order) { create :order_with_line_items, user: user }
|
|
611
|
-
|
|
612
|
-
before do
|
|
613
|
-
order.user_id = user.id
|
|
614
|
-
order.save!
|
|
615
|
-
end
|
|
616
|
-
|
|
617
|
-
context 'when the user has used this promo' do
|
|
618
|
-
before do
|
|
619
|
-
promotion.activate(order: order)
|
|
620
|
-
order.update_with_updater!
|
|
621
|
-
order.completed_at = Time.current
|
|
622
|
-
order.save!
|
|
623
|
-
end
|
|
624
|
-
|
|
625
|
-
context 'when the order is complete' do
|
|
626
|
-
it { is_expected.to be true }
|
|
627
|
-
|
|
628
|
-
context 'when the promotion was not eligible' do
|
|
629
|
-
let(:adjustment) { order.adjustments.first }
|
|
630
|
-
|
|
631
|
-
before do
|
|
632
|
-
adjustment.eligible = false
|
|
633
|
-
adjustment.save!
|
|
634
|
-
end
|
|
635
|
-
|
|
636
|
-
it { is_expected.to be false }
|
|
637
|
-
end
|
|
638
|
-
|
|
639
|
-
context 'when the only matching order is the excluded order' do
|
|
640
|
-
let(:excluded_order) { order }
|
|
641
|
-
it { is_expected.to be false }
|
|
642
|
-
end
|
|
643
|
-
end
|
|
644
|
-
|
|
645
|
-
context 'when the order is not complete' do
|
|
646
|
-
let(:order) { create :order, user: user }
|
|
647
|
-
it { is_expected.to be false }
|
|
648
|
-
end
|
|
649
|
-
end
|
|
650
|
-
|
|
651
|
-
context 'when the user has not used this promo' do
|
|
652
|
-
it { is_expected.to be false }
|
|
653
|
-
end
|
|
654
|
-
end
|
|
655
|
-
|
|
656
|
-
describe "adding items to the cart" do
|
|
657
|
-
let(:order) { create :order }
|
|
658
|
-
let(:line_item) { create :line_item, order: order }
|
|
659
|
-
let(:promo) { create :promotion_with_item_adjustment, adjustment_rate: 5, code: 'promo' }
|
|
660
|
-
let(:variant) { create :variant }
|
|
661
|
-
|
|
662
|
-
it "updates the promotions for new line items" do
|
|
663
|
-
expect(line_item.adjustments).to be_empty
|
|
664
|
-
expect(order.adjustment_total).to eq 0
|
|
665
|
-
|
|
666
|
-
promo.activate order: order
|
|
667
|
-
order.update_with_updater!
|
|
668
|
-
|
|
669
|
-
expect(line_item.adjustments.size).to eq(1)
|
|
670
|
-
expect(order.adjustment_total).to eq -5
|
|
671
|
-
|
|
672
|
-
other_line_item = order.contents.add(variant, 1, currency: order.currency)
|
|
673
|
-
|
|
674
|
-
expect(other_line_item).not_to eq line_item
|
|
675
|
-
expect(other_line_item.adjustments.size).to eq(1)
|
|
676
|
-
expect(order.adjustment_total).to eq -10
|
|
677
|
-
end
|
|
678
|
-
end
|
|
679
|
-
end
|