spree_core 3.0.5 → 3.0.6
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 +4 -0
- data/Gemfile +3 -0
- data/Rakefile +30 -0
- data/app/assets/javascripts/spree.js.coffee.erb +1 -1
- data/app/models/spree/ability.rb +1 -1
- data/app/models/spree/base.rb +3 -1
- data/app/models/spree/order_updater.rb +2 -1
- data/app/models/spree/price.rb +7 -12
- data/app/models/spree/product.rb +3 -2
- data/app/models/spree/reimbursement.rb +1 -1
- data/app/models/spree/state.rb +2 -0
- data/app/models/spree/zone.rb +1 -1
- data/lib/spree/core/version.rb +1 -1
- data/lib/spree/testing_support/shoulda_matcher_configuration.rb +6 -0
- data/script/rails +9 -0
- data/spec/fixtures/thinking-cat.jpg +0 -0
- data/spec/helpers/base_helper_spec.rb +137 -0
- data/spec/helpers/products_helper_spec.rb +224 -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/spree/core/controller_helpers/auth_spec.rb +101 -0
- data/spec/lib/spree/core/controller_helpers/order_spec.rb +95 -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/delegate_belongs_to_spec.rb +22 -0
- data/spec/lib/spree/core/importer/order_spec.rb +502 -0
- data/spec/lib/spree/core/validators/email_spec.rb +53 -0
- data/spec/lib/spree/localized_number_spec.rb +38 -0
- data/spec/lib/spree/migrations_spec.rb +34 -0
- data/spec/lib/spree/money_spec.rb +122 -0
- data/spec/lib/tasks/exchanges_spec.rb +136 -0
- data/spec/mailers/order_mailer_spec.rb +124 -0
- data/spec/mailers/reimbursement_mailer_spec.rb +47 -0
- data/spec/mailers/shipment_mailer_spec.rb +63 -0
- data/spec/mailers/test_mailer_spec.rb +24 -0
- data/spec/models/spree/ability_spec.rb +246 -0
- data/spec/models/spree/address_spec.rb +291 -0
- data/spec/models/spree/adjustable/adjustments_updater_spec.rb +286 -0
- data/spec/models/spree/adjustment_spec.rb +163 -0
- data/spec/models/spree/app_configuration_spec.rb +23 -0
- data/spec/models/spree/asset_spec.rb +25 -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.rb +8 -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 +29 -0
- data/spec/models/spree/calculator/tiered_flat_rate_spec.rb +40 -0
- data/spec/models/spree/calculator/tiered_percent_spec.rb +51 -0
- data/spec/models/spree/calculator_spec.rb +69 -0
- data/spec/models/spree/classification_spec.rb +93 -0
- data/spec/models/spree/concerns/display_money_spec.rb +43 -0
- data/spec/models/spree/country_spec.rb +18 -0
- data/spec/models/spree/credit_card_spec.rb +324 -0
- data/spec/models/spree/customer_return_spec.rb +262 -0
- data/spec/models/spree/exchange_spec.rb +75 -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 +54 -0
- data/spec/models/spree/image_spec.rb +5 -0
- data/spec/models/spree/inventory_unit_spec.rb +242 -0
- data/spec/models/spree/line_item_spec.rb +267 -0
- data/spec/models/spree/option_type_spec.rb +14 -0
- data/spec/models/spree/option_value_spec.rb +13 -0
- data/spec/models/spree/order/address_spec.rb +50 -0
- data/spec/models/spree/order/adjustments_spec.rb +29 -0
- data/spec/models/spree/order/callbacks_spec.rb +42 -0
- data/spec/models/spree/order/checkout_spec.rb +764 -0
- data/spec/models/spree/order/currency_updater_spec.rb +32 -0
- data/spec/models/spree/order/finalizing_spec.rb +117 -0
- data/spec/models/spree/order/helpers_spec.rb +5 -0
- data/spec/models/spree/order/payment_spec.rb +214 -0
- data/spec/models/spree/order/risk_assessment_spec.rb +84 -0
- data/spec/models/spree/order/shipments_spec.rb +43 -0
- data/spec/models/spree/order/state_machine_spec.rb +216 -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_contents_spec.rb +256 -0
- data/spec/models/spree/order_inventory_spec.rb +228 -0
- data/spec/models/spree/order_merger_spec.rb +133 -0
- data/spec/models/spree/order_spec.rb +954 -0
- data/spec/models/spree/order_updater_spec.rb +283 -0
- data/spec/models/spree/payment/gateway_options_spec.rb +119 -0
- data/spec/models/spree/payment_method_spec.rb +95 -0
- data/spec/models/spree/payment_spec.rb +926 -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 +348 -0
- data/spec/models/spree/preferences/scoped_store_spec.rb +58 -0
- data/spec/models/spree/preferences/store_spec.rb +46 -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_option_type_spec.rb +5 -0
- data/spec/models/spree/product_property_spec.rb +11 -0
- data/spec/models/spree/product_spec.rb +474 -0
- data/spec/models/spree/promotion/actions/create_adjustment_spec.rb +50 -0
- data/spec/models/spree/promotion/actions/create_item_adjustments_spec.rb +148 -0
- data/spec/models/spree/promotion/actions/create_line_items_spec.rb +86 -0
- data/spec/models/spree/promotion/actions/free_shipping_spec.rb +36 -0
- data/spec/models/spree/promotion/rules/first_order_spec.rb +75 -0
- data/spec/models/spree/promotion/rules/item_total_spec.rb +282 -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 +90 -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_action_spec.rb +10 -0
- data/spec/models/spree/promotion_category_spec.rb +17 -0
- data/spec/models/spree/promotion_handler/cart_spec.rb +102 -0
- data/spec/models/spree/promotion_handler/coupon_spec.rb +323 -0
- data/spec/models/spree/promotion_handler/free_shipping_spec.rb +48 -0
- data/spec/models/spree/promotion_handler/page_spec.rb +44 -0
- data/spec/models/spree/promotion_rule_spec.rb +29 -0
- data/spec/models/spree/promotion_spec.rb +603 -0
- data/spec/models/spree/property_spec.rb +5 -0
- data/spec/models/spree/prototype_spec.rb +5 -0
- data/spec/models/spree/refund_spec.rb +195 -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 +215 -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 +55 -0
- data/spec/models/spree/return_authorization_spec.rb +250 -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 +61 -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 +682 -0
- data/spec/models/spree/returns_calculator_spec.rb +14 -0
- data/spec/models/spree/shipment_spec.rb +740 -0
- data/spec/models/spree/shipping_calculator_spec.rb +45 -0
- data/spec/models/spree/shipping_category_spec.rb +5 -0
- data/spec/models/spree/shipping_method_spec.rb +88 -0
- data/spec/models/spree/shipping_rate_spec.rb +141 -0
- data/spec/models/spree/state_spec.rb +18 -0
- data/spec/models/spree/stock/availability_validator_spec.rb +36 -0
- data/spec/models/spree/stock/content_item_spec.rb +22 -0
- data/spec/models/spree/stock/coordinator_spec.rb +51 -0
- data/spec/models/spree/stock/differentiator_spec.rb +39 -0
- data/spec/models/spree/stock/estimator_spec.rb +154 -0
- data/spec/models/spree/stock/inventory_unit_builder_spec.rb +38 -0
- data/spec/models/spree/stock/package_spec.rb +194 -0
- data/spec/models/spree/stock/packer_spec.rb +70 -0
- data/spec/models/spree/stock/prioritizer_spec.rb +125 -0
- data/spec/models/spree/stock/quantifier_spec.rb +97 -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 +47 -0
- data/spec/models/spree/stock/splitter/weight_spec.rb +32 -0
- data/spec/models/spree/stock_item_spec.rb +410 -0
- data/spec/models/spree/stock_location_spec.rb +243 -0
- data/spec/models/spree/stock_movement_spec.rb +56 -0
- data/spec/models/spree/stock_transfer_spec.rb +50 -0
- data/spec/models/spree/store_spec.rb +50 -0
- data/spec/models/spree/tax_category_spec.rb +27 -0
- data/spec/models/spree/tax_rate_spec.rb +382 -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/user_spec.rb +130 -0
- data/spec/models/spree/validations/db_maximum_length_validator_spec.rb +24 -0
- data/spec/models/spree/variant_spec.rb +523 -0
- data/spec/models/spree/zone_spec.rb +444 -0
- data/spec/spec_helper.rb +74 -0
- data/spec/support/big_decimal.rb +5 -0
- data/spec/support/concerns/adjustment_source_spec.rb +23 -0
- data/spec/support/concerns/default_price_spec.rb +28 -0
- data/spec/support/rake.rb +13 -0
- data/spec/support/test_gateway.rb +2 -0
- data/spree_core.gemspec +48 -0
- metadata +185 -4
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Spree::PromotionCategory, :type => :model do
|
|
4
|
+
describe 'validation' do
|
|
5
|
+
let(:name) { 'Nom' }
|
|
6
|
+
subject { Spree::PromotionCategory.new name: name }
|
|
7
|
+
|
|
8
|
+
context 'when all required attributes are specified' do
|
|
9
|
+
it { is_expected.to be_valid }
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
context 'when name is missing' do
|
|
13
|
+
let(:name) { nil }
|
|
14
|
+
it { is_expected.not_to be_valid }
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,102 @@
|
|
|
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
|
+
|
|
9
|
+
let(:promotion) { Promotion.create(name: "At line items") }
|
|
10
|
+
let(:calculator) { Calculator::FlatPercentItemTotal.new(preferred_flat_percent: 10) }
|
|
11
|
+
|
|
12
|
+
subject { Cart.new(order, line_item) }
|
|
13
|
+
|
|
14
|
+
context "activates in LineItem level" do
|
|
15
|
+
let!(:action) { Promotion::Actions::CreateItemAdjustments.create(promotion: promotion, calculator: calculator) }
|
|
16
|
+
let(:adjustable) { line_item }
|
|
17
|
+
|
|
18
|
+
shared_context "creates the adjustment" do
|
|
19
|
+
it "creates the adjustment" do
|
|
20
|
+
expect {
|
|
21
|
+
subject.activate
|
|
22
|
+
}.to change { adjustable.adjustments.count }.by(1)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
context "promotion with no rules" do
|
|
27
|
+
include_context "creates the adjustment"
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
context "promotion includes item involved" do
|
|
31
|
+
let!(:rule) { Promotion::Rules::Product.create(products: [line_item.product], promotion: promotion) }
|
|
32
|
+
|
|
33
|
+
include_context "creates the adjustment"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
context "promotion has item total rule" do
|
|
37
|
+
let(:shirt) { create(:product) }
|
|
38
|
+
let!(:rule) { Promotion::Rules::ItemTotal.create(preferred_operator_min: 'gt', preferred_amount_min: 50, preferred_operator_max: 'lt', preferred_amount_max: 150, promotion: promotion) }
|
|
39
|
+
|
|
40
|
+
before do
|
|
41
|
+
# Makes the order eligible for this promotion
|
|
42
|
+
order.item_total = 100
|
|
43
|
+
order.save
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
include_context "creates the adjustment"
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
context "activates in Order level" do
|
|
51
|
+
let!(:action) { Promotion::Actions::CreateAdjustment.create(promotion: promotion, calculator: calculator) }
|
|
52
|
+
let(:adjustable) { order }
|
|
53
|
+
|
|
54
|
+
shared_context "creates the adjustment" do
|
|
55
|
+
it "creates the adjustment" do
|
|
56
|
+
expect {
|
|
57
|
+
subject.activate
|
|
58
|
+
}.to change { adjustable.adjustments.count }.by(1)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
context "promotion with no rules" do
|
|
63
|
+
before do
|
|
64
|
+
# Gives the calculator something to discount
|
|
65
|
+
order.item_total = 10
|
|
66
|
+
order.save
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
include_context "creates the adjustment"
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
context "promotion has item total rule" do
|
|
73
|
+
let(:shirt) { create(:product) }
|
|
74
|
+
let!(:rule) { Promotion::Rules::ItemTotal.create(preferred_operator_min: 'gt', preferred_amount_min: 50, preferred_operator_max: 'lt', preferred_amount_max: 150, promotion: promotion) }
|
|
75
|
+
|
|
76
|
+
before do
|
|
77
|
+
# Makes the order eligible for this promotion
|
|
78
|
+
order.item_total = 100
|
|
79
|
+
order.save
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
include_context "creates the adjustment"
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
context "activates promotions associated with the order" do
|
|
87
|
+
let(:promo) { create :promotion_with_item_adjustment, adjustment_rate: 5, code: 'promo' }
|
|
88
|
+
let(:adjustable) { line_item }
|
|
89
|
+
|
|
90
|
+
before do
|
|
91
|
+
order.promotions << promo
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it "creates the adjustment" do
|
|
95
|
+
expect {
|
|
96
|
+
subject.activate
|
|
97
|
+
}.to change { adjustable.adjustments.count }.by(1)
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
@@ -0,0 +1,323 @@
|
|
|
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
|
+
it "returns self in apply" do
|
|
11
|
+
expect(subject.apply).to be_a Coupon
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
context 'status messages' do
|
|
15
|
+
let(:coupon) { Coupon.new(order) }
|
|
16
|
+
|
|
17
|
+
describe "#set_success_code" do
|
|
18
|
+
let(:status) { :coupon_code_applied }
|
|
19
|
+
subject { coupon.set_success_code status }
|
|
20
|
+
|
|
21
|
+
it 'should have status_code' do
|
|
22
|
+
subject
|
|
23
|
+
expect(coupon.status_code).to eq(status)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it 'should have success message' do
|
|
27
|
+
subject
|
|
28
|
+
expect(coupon.success).to eq(Spree.t(status))
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
describe "#set_error_code" do
|
|
33
|
+
let(:status) { :coupon_code_not_found }
|
|
34
|
+
|
|
35
|
+
subject { coupon.set_error_code status }
|
|
36
|
+
|
|
37
|
+
it 'should have status_code' do
|
|
38
|
+
subject
|
|
39
|
+
expect(coupon.status_code).to eq(status)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it 'should have error message' do
|
|
43
|
+
subject
|
|
44
|
+
expect(coupon.error).to eq(Spree.t(status))
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
context "coupon code promotion doesnt exist" do
|
|
50
|
+
before { Promotion.create name: "promo", :code => nil }
|
|
51
|
+
|
|
52
|
+
it "doesnt fetch any promotion" do
|
|
53
|
+
expect(subject.promotion).to be_blank
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
context "with no actions defined" do
|
|
57
|
+
before { Promotion.create name: "promo", :code => "10off" }
|
|
58
|
+
|
|
59
|
+
it "populates error message" do
|
|
60
|
+
subject.apply
|
|
61
|
+
expect(subject.error).to eq Spree.t(:coupon_code_not_found)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
context "existing coupon code promotion" do
|
|
67
|
+
let!(:promotion) { Promotion.create name: "promo", :code => "10off" }
|
|
68
|
+
let!(:action) { Promotion::Actions::CreateItemAdjustments.create(promotion: promotion, calculator: calculator) }
|
|
69
|
+
let(:calculator) { Calculator::FlatRate.new(preferred_amount: 10) }
|
|
70
|
+
|
|
71
|
+
it "fetches with given code" do
|
|
72
|
+
expect(subject.promotion).to eq promotion
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
context "with a per-item adjustment action" do
|
|
76
|
+
let(:order) { create(:order_with_line_items, :line_items_count => 3) }
|
|
77
|
+
|
|
78
|
+
context "right coupon given" do
|
|
79
|
+
context "with correct coupon code casing" do
|
|
80
|
+
before { allow(order).to receive_messages :coupon_code => "10off" }
|
|
81
|
+
|
|
82
|
+
it "successfully activates promo" do
|
|
83
|
+
expect(order.total).to eq(130)
|
|
84
|
+
subject.apply
|
|
85
|
+
expect(subject.success).to be_present
|
|
86
|
+
order.line_items.each do |line_item|
|
|
87
|
+
expect(line_item.adjustments.count).to eq(1)
|
|
88
|
+
end
|
|
89
|
+
# Ensure that applying the adjustment actually affects the order's total!
|
|
90
|
+
expect(order.reload.total).to eq(100)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
it "coupon already applied to the order" do
|
|
94
|
+
subject.apply
|
|
95
|
+
expect(subject.success).to be_present
|
|
96
|
+
subject.apply
|
|
97
|
+
expect(subject.error).to eq Spree.t(:coupon_code_already_applied)
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# Regression test for #4211
|
|
102
|
+
context "with incorrect coupon code casing" do
|
|
103
|
+
before { allow(order).to receive_messages :coupon_code => "10OFF" }
|
|
104
|
+
it "successfully activates promo" do
|
|
105
|
+
expect(order.total).to eq(130)
|
|
106
|
+
subject.apply
|
|
107
|
+
expect(subject.success).to be_present
|
|
108
|
+
order.line_items.each do |line_item|
|
|
109
|
+
expect(line_item.adjustments.count).to eq(1)
|
|
110
|
+
end
|
|
111
|
+
# Ensure that applying the adjustment actually affects the order's total!
|
|
112
|
+
expect(order.reload.total).to eq(100)
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
context "coexists with a non coupon code promo" do
|
|
118
|
+
let!(:order) { Order.create }
|
|
119
|
+
|
|
120
|
+
before do
|
|
121
|
+
allow(order).to receive_messages :coupon_code => "10off"
|
|
122
|
+
calculator = Calculator::FlatRate.new(preferred_amount: 10)
|
|
123
|
+
general_promo = Promotion.create name: "General Promo"
|
|
124
|
+
general_action = Promotion::Actions::CreateItemAdjustments.create(promotion: general_promo, calculator: calculator)
|
|
125
|
+
|
|
126
|
+
order.contents.add create(:variant)
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# regression spec for #4515
|
|
130
|
+
it "successfully activates promo" do
|
|
131
|
+
subject.apply
|
|
132
|
+
expect(subject).to be_successful
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
context "with a free-shipping adjustment action" do
|
|
138
|
+
let!(:action) { Promotion::Actions::FreeShipping.create(promotion: promotion) }
|
|
139
|
+
context "right coupon code given" do
|
|
140
|
+
let(:order) { create(:order_with_line_items, :line_items_count => 3) }
|
|
141
|
+
|
|
142
|
+
before { allow(order).to receive_messages :coupon_code => "10off" }
|
|
143
|
+
|
|
144
|
+
it "successfully activates promo" do
|
|
145
|
+
expect(order.total).to eq(130)
|
|
146
|
+
subject.apply
|
|
147
|
+
expect(subject.success).to be_present
|
|
148
|
+
|
|
149
|
+
expect(order.shipment_adjustments.count).to eq(1)
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
it "coupon already applied to the order" do
|
|
153
|
+
subject.apply
|
|
154
|
+
expect(subject.success).to be_present
|
|
155
|
+
subject.apply
|
|
156
|
+
expect(subject.error).to eq Spree.t(:coupon_code_already_applied)
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
context "with a whole-order adjustment action" do
|
|
162
|
+
let!(:action) { Promotion::Actions::CreateAdjustment.create(promotion: promotion, calculator: calculator) }
|
|
163
|
+
context "right coupon given" do
|
|
164
|
+
let(:order) { create(:order) }
|
|
165
|
+
let(:calculator) { Calculator::FlatRate.new(preferred_amount: 10) }
|
|
166
|
+
|
|
167
|
+
before do
|
|
168
|
+
allow(order).to receive_messages({
|
|
169
|
+
:coupon_code => "10off",
|
|
170
|
+
# These need to be here so that promotion adjustment "wins"
|
|
171
|
+
:item_total => 50,
|
|
172
|
+
:ship_total => 10
|
|
173
|
+
})
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
it "successfully activates promo" do
|
|
177
|
+
subject.apply
|
|
178
|
+
expect(subject.success).to be_present
|
|
179
|
+
expect(order.adjustments.count).to eq(1)
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
it "coupon already applied to the order" do
|
|
183
|
+
subject.apply
|
|
184
|
+
expect(subject.success).to be_present
|
|
185
|
+
subject.apply
|
|
186
|
+
expect(subject.error).to eq Spree.t(:coupon_code_already_applied)
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
it "coupon fails to activate" do
|
|
190
|
+
allow_any_instance_of(Spree::Promotion).to receive(:activate).and_return false
|
|
191
|
+
subject.apply
|
|
192
|
+
expect(subject.error).to eq Spree.t(:coupon_code_unknown_error)
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
it "coupon code hit max usage" do
|
|
197
|
+
promotion.update_column(:usage_limit, 1)
|
|
198
|
+
coupon = Coupon.new(order)
|
|
199
|
+
coupon.apply
|
|
200
|
+
expect(coupon.successful?).to be true
|
|
201
|
+
|
|
202
|
+
order_2 = create(:order)
|
|
203
|
+
allow(order_2).to receive_messages :coupon_code => "10off"
|
|
204
|
+
coupon = Coupon.new(order_2)
|
|
205
|
+
coupon.apply
|
|
206
|
+
expect(coupon.successful?).to be false
|
|
207
|
+
expect(coupon.error).to eq Spree.t(:coupon_code_max_usage)
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
context "when the a new coupon is less good" do
|
|
211
|
+
let!(:action_5) { Promotion::Actions::CreateAdjustment.create(promotion: promotion_5, calculator: calculator_5) }
|
|
212
|
+
let(:calculator_5) { Calculator::FlatRate.new(preferred_amount: 5) }
|
|
213
|
+
let!(:promotion_5) { Promotion.create name: "promo", :code => "5off" }
|
|
214
|
+
|
|
215
|
+
it 'notifies of better deal' do
|
|
216
|
+
subject.apply
|
|
217
|
+
allow(order).to receive_messages( { coupon_code: '5off' } )
|
|
218
|
+
coupon = Coupon.new(order).apply
|
|
219
|
+
expect(coupon.error).to eq Spree.t(:coupon_code_better_exists)
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
context "for an order with taxable line items" do
|
|
226
|
+
before(:each) do
|
|
227
|
+
@country = create(:country)
|
|
228
|
+
@zone = create(:zone, :name => "Country Zone", :default_tax => true, :zone_members => [])
|
|
229
|
+
@zone.zone_members.create(:zoneable => @country)
|
|
230
|
+
@category = Spree::TaxCategory.create :name => "Taxable Foo"
|
|
231
|
+
@rate1 = Spree::TaxRate.create(
|
|
232
|
+
:amount => 0.10,
|
|
233
|
+
:calculator => Spree::Calculator::DefaultTax.create,
|
|
234
|
+
:tax_category => @category,
|
|
235
|
+
:zone => @zone
|
|
236
|
+
)
|
|
237
|
+
|
|
238
|
+
@order = Spree::Order.create!
|
|
239
|
+
allow(@order).to receive_messages :coupon_code => "10off"
|
|
240
|
+
end
|
|
241
|
+
context "and the product price is less than promo discount" do
|
|
242
|
+
before(:each) do
|
|
243
|
+
3.times do |i|
|
|
244
|
+
taxable = create(:product, :tax_category => @category, :price => 9.0)
|
|
245
|
+
@order.contents.add(taxable.master, 1)
|
|
246
|
+
end
|
|
247
|
+
end
|
|
248
|
+
it "successfully applies the promo" do
|
|
249
|
+
# 3 * (9 + 0.9)
|
|
250
|
+
expect(@order.total).to eq(29.7)
|
|
251
|
+
coupon = Coupon.new(@order)
|
|
252
|
+
coupon.apply
|
|
253
|
+
expect(coupon.success).to be_present
|
|
254
|
+
# 3 * ((9 - [9,10].min) + 0)
|
|
255
|
+
expect(@order.reload.total).to eq(0)
|
|
256
|
+
expect(@order.additional_tax_total).to eq(0)
|
|
257
|
+
end
|
|
258
|
+
end
|
|
259
|
+
context "and the product price is greater than promo discount" do
|
|
260
|
+
before(:each) do
|
|
261
|
+
3.times do |i|
|
|
262
|
+
taxable = create(:product, :tax_category => @category, :price => 11.0)
|
|
263
|
+
@order.contents.add(taxable.master, 2)
|
|
264
|
+
end
|
|
265
|
+
end
|
|
266
|
+
it "successfully applies the promo" do
|
|
267
|
+
# 3 * (22 + 2.2)
|
|
268
|
+
expect(@order.total.to_f).to eq(72.6)
|
|
269
|
+
coupon = Coupon.new(@order)
|
|
270
|
+
coupon.apply
|
|
271
|
+
expect(coupon.success).to be_present
|
|
272
|
+
# 3 * ( (22 - 10) + 1.2)
|
|
273
|
+
expect(@order.reload.total).to eq(39.6)
|
|
274
|
+
expect(@order.additional_tax_total).to eq(3.6)
|
|
275
|
+
end
|
|
276
|
+
end
|
|
277
|
+
context "and multiple quantity per line item" do
|
|
278
|
+
before(:each) do
|
|
279
|
+
twnty_off = Promotion.create name: "promo", :code => "20off"
|
|
280
|
+
twnty_off_calc = Calculator::FlatRate.new(preferred_amount: 20)
|
|
281
|
+
Promotion::Actions::CreateItemAdjustments.create(promotion: twnty_off,
|
|
282
|
+
calculator: twnty_off_calc)
|
|
283
|
+
|
|
284
|
+
allow(@order).to receive(:coupon_code).and_call_original
|
|
285
|
+
allow(@order).to receive_messages :coupon_code => "20off"
|
|
286
|
+
3.times do |i|
|
|
287
|
+
taxable = create(:product, :tax_category => @category, :price => 10.0)
|
|
288
|
+
@order.contents.add(taxable.master, 2)
|
|
289
|
+
end
|
|
290
|
+
end
|
|
291
|
+
it "successfully applies the promo" do
|
|
292
|
+
# 3 * ((2 * 10) + 2.0)
|
|
293
|
+
expect(@order.total.to_f).to eq(66)
|
|
294
|
+
coupon = Coupon.new(@order)
|
|
295
|
+
coupon.apply
|
|
296
|
+
expect(coupon.success).to be_present
|
|
297
|
+
# 0
|
|
298
|
+
expect(@order.reload.total).to eq(0)
|
|
299
|
+
expect(@order.additional_tax_total).to eq(0)
|
|
300
|
+
end
|
|
301
|
+
end
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
context "with a CreateLineItems action" do
|
|
305
|
+
let!(:variant) { create(:variant) }
|
|
306
|
+
let!(:action) { Promotion::Actions::CreateLineItems.create(promotion: promotion, promotion_action_line_items_attributes: { :'0' => { variant_id: variant.id }}) }
|
|
307
|
+
let(:order) { create(:order) }
|
|
308
|
+
|
|
309
|
+
before do
|
|
310
|
+
allow(order).to receive_messages(coupon_code: "10off")
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
it "successfully activates promo" do
|
|
314
|
+
subject.apply
|
|
315
|
+
expect(subject.success).to be_present
|
|
316
|
+
expect(order.line_items.pluck(:variant_id)).to include(variant.id)
|
|
317
|
+
end
|
|
318
|
+
end
|
|
319
|
+
|
|
320
|
+
end
|
|
321
|
+
end
|
|
322
|
+
end
|
|
323
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
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
|