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,67 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Spree::Promotion::Rules::ItemTotal, :type => :model do
|
|
4
|
+
let(:rule) { Spree::Promotion::Rules::ItemTotal.new }
|
|
5
|
+
let(:order) { double(:order) }
|
|
6
|
+
|
|
7
|
+
before { rule.preferred_amount = 50 }
|
|
8
|
+
|
|
9
|
+
context "preferred operator set to gt" do
|
|
10
|
+
before { rule.preferred_operator = 'gt' }
|
|
11
|
+
|
|
12
|
+
it "should be eligible when item total is greater than preferred amount" do
|
|
13
|
+
allow(order).to receive_messages :item_total => 51
|
|
14
|
+
expect(rule).to be_eligible(order)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
context "when item total is equal to preferred amount" do
|
|
18
|
+
before { allow(order).to receive_messages item_total: 50 }
|
|
19
|
+
it "is not eligible" do
|
|
20
|
+
expect(rule).not_to be_eligible(order)
|
|
21
|
+
end
|
|
22
|
+
it "set an error message" do
|
|
23
|
+
rule.eligible?(order)
|
|
24
|
+
expect(rule.eligibility_errors.full_messages.first).
|
|
25
|
+
to eq "This coupon code can't be applied to orders less than or equal to $50.00."
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
context "when item total is lower than preferred amount" do
|
|
30
|
+
before { allow(order).to receive_messages item_total: 49 }
|
|
31
|
+
it "is not eligible" do
|
|
32
|
+
expect(rule).not_to be_eligible(order)
|
|
33
|
+
end
|
|
34
|
+
it "set an error message" do
|
|
35
|
+
rule.eligible?(order)
|
|
36
|
+
expect(rule.eligibility_errors.full_messages.first).
|
|
37
|
+
to eq "This coupon code can't be applied to orders less than or equal to $50.00."
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
context "preferred operator set to gte" do
|
|
43
|
+
before { rule.preferred_operator = 'gte' }
|
|
44
|
+
|
|
45
|
+
it "should be eligible when item total is greater than preferred amount" do
|
|
46
|
+
allow(order).to receive_messages :item_total => 51
|
|
47
|
+
expect(rule).to be_eligible(order)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it "should be eligible when item total is equal to preferred amount" do
|
|
51
|
+
allow(order).to receive_messages :item_total => 50
|
|
52
|
+
expect(rule).to be_eligible(order)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
context "when item total is lower than preferred amount" do
|
|
56
|
+
before { allow(order).to receive_messages item_total: 49 }
|
|
57
|
+
it "is not eligible" do
|
|
58
|
+
expect(rule).not_to be_eligible(order)
|
|
59
|
+
end
|
|
60
|
+
it "set an error message" do
|
|
61
|
+
rule.eligible?(order)
|
|
62
|
+
expect(rule.eligibility_errors.full_messages.first).
|
|
63
|
+
to eq "This coupon code can't be applied to orders less than $50.00."
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Spree::Promotion::Rules::NthOrder do
|
|
4
|
+
describe "#applicable?" do
|
|
5
|
+
subject { described_class.new.applicable?(promotable) }
|
|
6
|
+
|
|
7
|
+
context "when the promotable is an order" do
|
|
8
|
+
let(:promotable) { Spree::Order.new }
|
|
9
|
+
|
|
10
|
+
it { is_expected.to be true }
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
context "when the promotable is not a order" do
|
|
14
|
+
let(:promotable) { "not an order" }
|
|
15
|
+
|
|
16
|
+
it { is_expected.to be false }
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
describe "eligible?" do
|
|
21
|
+
let(:instance) { described_class.new }
|
|
22
|
+
subject { instance.eligible?(order) }
|
|
23
|
+
|
|
24
|
+
before do
|
|
25
|
+
instance.preferred_nth_order = 2
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
context "when the order does not have a user" do
|
|
29
|
+
let(:order) { Spree::Order.new }
|
|
30
|
+
|
|
31
|
+
it { is_expected.to be false }
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
context "when the order has a user" do
|
|
35
|
+
let(:order) { create :order }
|
|
36
|
+
let(:user) { order.user }
|
|
37
|
+
|
|
38
|
+
context "when the user has completed orders" do
|
|
39
|
+
before do
|
|
40
|
+
old_order = create :completed_order_with_totals, user: user
|
|
41
|
+
old_order.update_attributes(completed_at: 1.day.ago)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
context "when this order will be the 'nth' order" do
|
|
45
|
+
it { is_expected.to be true }
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
context "when this order is completed and is still the 'nth' order" do
|
|
49
|
+
before do
|
|
50
|
+
order.update_attributes(completed_at: Time.now)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
it { is_expected.to be true }
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
context "when this order will not be the 'nth' order" do
|
|
57
|
+
before do
|
|
58
|
+
instance.preferred_nth_order = 100
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it { is_expected.to be false }
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
context "when the user has no completed orders " do
|
|
66
|
+
it { is_expected.to be false }
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Spree::Promotion::Rules::OneUsePerUser, :type => :model do
|
|
4
|
+
let(:rule) { described_class.new }
|
|
5
|
+
|
|
6
|
+
describe '#eligible?(order)' do
|
|
7
|
+
subject { rule.eligible?(order) }
|
|
8
|
+
let(:order) { double Spree::Order, user: user }
|
|
9
|
+
let(:user) { double Spree::LegacyUser }
|
|
10
|
+
let(:promotion) { stub_model Spree::Promotion, used_by?: used_by }
|
|
11
|
+
let(:used_by) { false }
|
|
12
|
+
|
|
13
|
+
before { rule.promotion = promotion }
|
|
14
|
+
|
|
15
|
+
context 'when the order is assigned to a user' do
|
|
16
|
+
context 'when the user has used this promotion before' do
|
|
17
|
+
let(:used_by) { true }
|
|
18
|
+
|
|
19
|
+
it { is_expected.to be false }
|
|
20
|
+
it "sets an error message" do
|
|
21
|
+
subject
|
|
22
|
+
expect(rule.eligibility_errors.full_messages.first).
|
|
23
|
+
to eq "This coupon code can only be used once per user."
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
context 'when the user has not used this promotion before' do
|
|
28
|
+
it { is_expected.to be true }
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
context 'when the order is not assigned to a user' do
|
|
33
|
+
let(:user) { nil }
|
|
34
|
+
it { is_expected.to be false }
|
|
35
|
+
it "sets an error message" do
|
|
36
|
+
subject
|
|
37
|
+
expect(rule.eligibility_errors.full_messages.first).
|
|
38
|
+
to eq "You need to login before applying this coupon code."
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Spree::Promotion::Rules::OptionValue do
|
|
4
|
+
let(:rule) { Spree::Promotion::Rules::OptionValue.new }
|
|
5
|
+
|
|
6
|
+
describe "#preferred_eligible_values" do
|
|
7
|
+
subject { rule.preferred_eligible_values }
|
|
8
|
+
it "assigns a nicely formatted hash" do
|
|
9
|
+
rule.preferred_eligible_values = Hash["5" => "1,2", "6" => "1"]
|
|
10
|
+
expect(subject).to eq Hash[5 => [1, 2], 6 => [1]]
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
describe "#applicable?" do
|
|
15
|
+
subject { rule.applicable?(promotable) }
|
|
16
|
+
context "when promotable is an order" do
|
|
17
|
+
let(:promotable) { Spree::Order.new }
|
|
18
|
+
it { is_expected.to be true }
|
|
19
|
+
end
|
|
20
|
+
context "when promotable is not an order" do
|
|
21
|
+
let(:promotable) { Spree::LineItem.new }
|
|
22
|
+
it { is_expected.to be false }
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
describe "#eligible?" do
|
|
27
|
+
let(:variant) { create :variant }
|
|
28
|
+
let(:line_item) { create :line_item, variant: variant }
|
|
29
|
+
let(:promotable) { line_item.order }
|
|
30
|
+
subject { rule.eligible?(promotable) }
|
|
31
|
+
context "when there are any applicable line items" do
|
|
32
|
+
before do
|
|
33
|
+
rule.preferred_eligible_values = Hash[line_item.product.id => [
|
|
34
|
+
line_item.variant.option_values.pluck(:id).first
|
|
35
|
+
]]
|
|
36
|
+
end
|
|
37
|
+
it { is_expected.to be true }
|
|
38
|
+
end
|
|
39
|
+
context "when there are no applicable line items" do
|
|
40
|
+
before do
|
|
41
|
+
rule.preferred_eligible_values = Hash[99 => [99]]
|
|
42
|
+
end
|
|
43
|
+
it { is_expected.to be false }
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
describe "#actionable?" do
|
|
48
|
+
let(:line_item) { create :line_item }
|
|
49
|
+
let(:option_value_blue) do
|
|
50
|
+
create(
|
|
51
|
+
:option_value,
|
|
52
|
+
name: 'Blue',
|
|
53
|
+
presentation: 'Blue',
|
|
54
|
+
option_type: create(
|
|
55
|
+
:option_type,
|
|
56
|
+
name: 'foo-colour',
|
|
57
|
+
presentation: 'Colour'
|
|
58
|
+
)
|
|
59
|
+
)
|
|
60
|
+
end
|
|
61
|
+
let(:option_value_medium) do
|
|
62
|
+
create(
|
|
63
|
+
:option_value,
|
|
64
|
+
name: 'Medium',
|
|
65
|
+
presentation: 'M'
|
|
66
|
+
)
|
|
67
|
+
end
|
|
68
|
+
before do
|
|
69
|
+
line_item.variant.option_values << option_value_blue
|
|
70
|
+
rule.preferred_eligible_values = Hash[product_id => option_value_ids]
|
|
71
|
+
end
|
|
72
|
+
subject { rule.actionable?(line_item) }
|
|
73
|
+
context "when the line item has the correct product" do
|
|
74
|
+
let(:product_id) { line_item.product.id }
|
|
75
|
+
context "when all of the option values match" do
|
|
76
|
+
let(:option_value_ids) { [option_value_blue.id] }
|
|
77
|
+
it { is_expected.to be true }
|
|
78
|
+
end
|
|
79
|
+
context "when any of the option values match" do
|
|
80
|
+
let(:option_value_ids) { [option_value_blue.id, option_value_medium.id] }
|
|
81
|
+
it { is_expected.to be true }
|
|
82
|
+
end
|
|
83
|
+
context "when none of the option values match" do
|
|
84
|
+
let(:option_value_ids) { [option_value_medium.id] }
|
|
85
|
+
it { is_expected.to be false }
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
context "when the line item's product doesn't match" do
|
|
89
|
+
let(:product_id) { 99 }
|
|
90
|
+
let(:option_value_ids) { [99] }
|
|
91
|
+
it { is_expected.to be false }
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Spree::Promotion::Rules::Product, :type => :model do
|
|
4
|
+
let(:rule) { Spree::Promotion::Rules::Product.new(rule_options) }
|
|
5
|
+
let(:rule_options) { {} }
|
|
6
|
+
|
|
7
|
+
context "#eligible?(order)" do
|
|
8
|
+
let(:order) { Spree::Order.new }
|
|
9
|
+
|
|
10
|
+
it "should be eligible if there are no products" do
|
|
11
|
+
allow(rule).to receive_messages(:eligible_products => [])
|
|
12
|
+
expect(rule).to be_eligible(order)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
before do
|
|
16
|
+
3.times { |i| instance_variable_set("@product#{i}", mock_model(Spree::Product)) }
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
context "with 'any' match policy" do
|
|
20
|
+
let(:rule_options) { super().merge(preferred_match_policy: 'any') }
|
|
21
|
+
|
|
22
|
+
it "should be eligible if any of the products is in eligible products" do
|
|
23
|
+
allow(order).to receive_messages(:products => [@product1, @product2])
|
|
24
|
+
allow(rule).to receive_messages(:eligible_products => [@product2, @product3])
|
|
25
|
+
expect(rule).to be_eligible(order)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
context "when none of the products are eligible products" do
|
|
29
|
+
before do
|
|
30
|
+
allow(order).to receive_messages(products: [@product1])
|
|
31
|
+
allow(rule).to receive_messages(eligible_products: [@product2, @product3])
|
|
32
|
+
end
|
|
33
|
+
it { expect(rule).not_to be_eligible(order) }
|
|
34
|
+
it "sets an error message" do
|
|
35
|
+
rule.eligible?(order)
|
|
36
|
+
expect(rule.eligibility_errors.full_messages.first).
|
|
37
|
+
to eq "You need to add an applicable product before applying this coupon code."
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
context "with 'all' match policy" do
|
|
43
|
+
let(:rule_options) { super().merge(preferred_match_policy: 'all') }
|
|
44
|
+
|
|
45
|
+
it "should be eligible if all of the eligible products are ordered" do
|
|
46
|
+
allow(order).to receive_messages(:products => [@product3, @product2, @product1])
|
|
47
|
+
allow(rule).to receive_messages(:eligible_products => [@product2, @product3])
|
|
48
|
+
expect(rule).to be_eligible(order)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
context "when any of the eligible products is not ordered" do
|
|
52
|
+
before do
|
|
53
|
+
allow(order).to receive_messages(products: [@product1, @product2])
|
|
54
|
+
allow(rule).to receive_messages(eligible_products: [@product1, @product2, @product3])
|
|
55
|
+
end
|
|
56
|
+
it { expect(rule).not_to be_eligible(order) }
|
|
57
|
+
it "sets an error message" do
|
|
58
|
+
rule.eligible?(order)
|
|
59
|
+
expect(rule.eligibility_errors.full_messages.first).
|
|
60
|
+
to eq "This coupon code can't be applied because you don't have all of the necessary products in your cart."
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
context "with 'none' match policy" do
|
|
66
|
+
let(:rule_options) { super().merge(preferred_match_policy: 'none') }
|
|
67
|
+
|
|
68
|
+
it "should be eligible if none of the order's products are in eligible products" do
|
|
69
|
+
allow(order).to receive_messages(:products => [@product1])
|
|
70
|
+
allow(rule).to receive_messages(:eligible_products => [@product2, @product3])
|
|
71
|
+
expect(rule).to be_eligible(order)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
context "when any of the order's products are in eligible products" do
|
|
75
|
+
before do
|
|
76
|
+
allow(order).to receive_messages(products: [@product1, @product2])
|
|
77
|
+
allow(rule).to receive_messages(eligible_products: [@product2, @product3])
|
|
78
|
+
end
|
|
79
|
+
it { expect(rule).not_to be_eligible(order) }
|
|
80
|
+
it "sets an error message" do
|
|
81
|
+
rule.eligible?(order)
|
|
82
|
+
expect(rule.eligibility_errors.full_messages.first).
|
|
83
|
+
to eq "Your cart contains a product that prevents this coupon code from being applied."
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
describe '#actionable?' do
|
|
90
|
+
subject do
|
|
91
|
+
rule.actionable?(line_item)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
let(:rule_line_item) { Spree::LineItem.new(product: rule_product) }
|
|
95
|
+
let(:other_line_item) { Spree::LineItem.new(product: other_product) }
|
|
96
|
+
|
|
97
|
+
let(:rule_options) { super().merge(products: [rule_product]) }
|
|
98
|
+
let(:rule_product) { mock_model(Spree::Product) }
|
|
99
|
+
let(:other_product) { mock_model(Spree::Product) }
|
|
100
|
+
|
|
101
|
+
context "with 'any' match policy" do
|
|
102
|
+
let(:rule_options) { super().merge(preferred_match_policy: 'any') }
|
|
103
|
+
|
|
104
|
+
context 'for product in rule' do
|
|
105
|
+
let(:line_item) { rule_line_item }
|
|
106
|
+
it { is_expected.to be_truthy }
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
context 'for product not in rule' do
|
|
110
|
+
let(:line_item) { other_line_item }
|
|
111
|
+
it { is_expected.to be_falsey }
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
context "with 'all' match policy" do
|
|
116
|
+
let(:rule_options) { super().merge(preferred_match_policy: 'all') }
|
|
117
|
+
|
|
118
|
+
context 'for product in rule' do
|
|
119
|
+
let(:line_item) { rule_line_item }
|
|
120
|
+
it { is_expected.to be_truthy }
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
context 'for product not in rule' do
|
|
124
|
+
let(:line_item) { other_line_item }
|
|
125
|
+
it { is_expected.to be_falsey }
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
context "with 'none' match policy" do
|
|
130
|
+
let(:rule_options) { super().merge(preferred_match_policy: 'none') }
|
|
131
|
+
|
|
132
|
+
context 'for product in rule' do
|
|
133
|
+
let(:line_item) { rule_line_item }
|
|
134
|
+
it { is_expected.to be_falsey }
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
context 'for product not in rule' do
|
|
138
|
+
let(:line_item) { other_line_item }
|
|
139
|
+
it { is_expected.to be_truthy }
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Spree::Promotion::Rules::Taxon, :type => :model do
|
|
4
|
+
let(:rule) { Spree::Promotion::Rules::Taxon.create!(promotion: create(:promotion)) }
|
|
5
|
+
|
|
6
|
+
context '#elegible?(order)' do
|
|
7
|
+
let(:taxon){ create :taxon, name: 'first' }
|
|
8
|
+
let(:taxon2){ create :taxon, name: 'second'}
|
|
9
|
+
let(:order){ create :order_with_line_items }
|
|
10
|
+
|
|
11
|
+
before do
|
|
12
|
+
rule.save
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
context 'with any match policy' do
|
|
16
|
+
before do
|
|
17
|
+
rule.preferred_match_policy = 'any'
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it 'is eligible if order does have any prefered taxon' do
|
|
21
|
+
order.products.first.taxons << taxon
|
|
22
|
+
rule.taxons << taxon
|
|
23
|
+
expect(rule).to be_eligible(order)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
context 'when order contains items from different taxons' do
|
|
27
|
+
before do
|
|
28
|
+
order.products.first.taxons << taxon
|
|
29
|
+
rule.taxons << taxon
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it 'should act on a product within the eligible taxon' do
|
|
33
|
+
expect(rule).to be_actionable(order.line_items.last)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it 'should not act on a product in another taxon' do
|
|
37
|
+
order.line_items << create(:line_item, product: create(:product, taxons: [taxon2]))
|
|
38
|
+
expect(rule).not_to be_actionable(order.line_items.last)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
context "when order does not have any prefered taxon" do
|
|
43
|
+
before { rule.taxons << taxon2 }
|
|
44
|
+
it { expect(rule).not_to be_eligible(order) }
|
|
45
|
+
it "sets an error message" do
|
|
46
|
+
rule.eligible?(order)
|
|
47
|
+
expect(rule.eligibility_errors.full_messages.first).
|
|
48
|
+
to eq "You need to add a product from an applicable category before applying this coupon code."
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
context 'when a product has a taxon child of a taxon rule' do
|
|
53
|
+
before do
|
|
54
|
+
taxon.children << taxon2
|
|
55
|
+
order.products.first.taxons << taxon2
|
|
56
|
+
rule.taxons << taxon2
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it{ expect(rule).to be_eligible(order) }
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
context 'with all match policy' do
|
|
64
|
+
before do
|
|
65
|
+
rule.preferred_match_policy = 'all'
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it 'is eligible order has all prefered taxons' do
|
|
69
|
+
order.products.first.taxons << taxon2
|
|
70
|
+
order.products.last.taxons << taxon
|
|
71
|
+
|
|
72
|
+
rule.taxons = [taxon, taxon2]
|
|
73
|
+
|
|
74
|
+
expect(rule).to be_eligible(order)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
context "when order does not have all prefered taxons" do
|
|
78
|
+
before { rule.taxons << taxon }
|
|
79
|
+
it { expect(rule).not_to be_eligible(order) }
|
|
80
|
+
it "sets an error message" do
|
|
81
|
+
rule.eligible?(order)
|
|
82
|
+
expect(rule.eligibility_errors.full_messages.first).
|
|
83
|
+
to eq "You need to add a product from all applicable categories before applying this coupon code."
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
context 'when a product has a taxon child of a taxon rule' do
|
|
88
|
+
let(:taxon3){ create :taxon }
|
|
89
|
+
|
|
90
|
+
before do
|
|
91
|
+
taxon.children << taxon2
|
|
92
|
+
order.products.first.taxons << taxon2
|
|
93
|
+
order.products.last.taxons << taxon3
|
|
94
|
+
rule.taxons << taxon2
|
|
95
|
+
rule.taxons << taxon3
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it{ expect(rule).to be_eligible(order) }
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|