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,286 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Spree
|
|
4
|
+
module Adjustable
|
|
5
|
+
describe AdjustmentsUpdater do
|
|
6
|
+
let(:order) { create :order_with_line_items, line_items_count: 1 }
|
|
7
|
+
let(:line_item) { order.line_items.first }
|
|
8
|
+
|
|
9
|
+
let(:subject) { AdjustmentsUpdater.new(line_item) }
|
|
10
|
+
let(:order_subject) { AdjustmentsUpdater.new(order) }
|
|
11
|
+
|
|
12
|
+
context '#update' do
|
|
13
|
+
it "updates a linked adjustment" do
|
|
14
|
+
tax_rate = create(:tax_rate, amount: 0.05)
|
|
15
|
+
create(:adjustment, order: order, source: tax_rate, adjustable: line_item)
|
|
16
|
+
line_item.price = 10
|
|
17
|
+
line_item.tax_category = tax_rate.tax_category
|
|
18
|
+
|
|
19
|
+
subject.update
|
|
20
|
+
expect(line_item.adjustment_total).to eq(0.5)
|
|
21
|
+
expect(line_item.additional_tax_total).to eq(0.5)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
context "taxes and promotions" do
|
|
26
|
+
let!(:tax_rate) do
|
|
27
|
+
create(:tax_rate, amount: 0.05)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
let!(:promotion) do
|
|
31
|
+
Spree::Promotion.create(name: "$10 off")
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
let!(:promotion_action) do
|
|
35
|
+
calculator = Calculator::FlatRate.new(preferred_amount: 10)
|
|
36
|
+
Promotion::Actions::CreateItemAdjustments.create(calculator: calculator,
|
|
37
|
+
promotion: promotion)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
before do
|
|
41
|
+
line_item.price = 20
|
|
42
|
+
line_item.tax_category = tax_rate.tax_category
|
|
43
|
+
line_item.save
|
|
44
|
+
create(:adjustment, order: order, source: promotion_action, adjustable: line_item)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
context "tax included in price" do
|
|
48
|
+
before do
|
|
49
|
+
create(:adjustment, source: tax_rate,
|
|
50
|
+
adjustable: line_item,
|
|
51
|
+
order: order,
|
|
52
|
+
included: true)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it "tax has no bearing on final price" do
|
|
56
|
+
subject.update
|
|
57
|
+
line_item.reload
|
|
58
|
+
expect(line_item.included_tax_total).to eq(0.5)
|
|
59
|
+
expect(line_item.additional_tax_total).to eq(0)
|
|
60
|
+
expect(line_item.promo_total).to eq(-10)
|
|
61
|
+
expect(line_item.adjustment_total).to eq(-10)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
it "tax linked to order" do
|
|
65
|
+
order_subject.update
|
|
66
|
+
order.reload
|
|
67
|
+
expect(order.included_tax_total).to eq(0.5)
|
|
68
|
+
expect(order.additional_tax_total).to eq(00)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
context "tax excluded from price" do
|
|
73
|
+
before do
|
|
74
|
+
create(:adjustment, source: tax_rate,
|
|
75
|
+
adjustable: line_item,
|
|
76
|
+
order: order,
|
|
77
|
+
included: false)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
it "tax applies to line item" do
|
|
81
|
+
subject.update
|
|
82
|
+
line_item.reload
|
|
83
|
+
# Taxable amount is: $20 (base) - $10 (promotion) = $10
|
|
84
|
+
# Tax rate is 5% (of $10).
|
|
85
|
+
expect(line_item.included_tax_total).to eq(0)
|
|
86
|
+
expect(line_item.additional_tax_total).to eq(0.5)
|
|
87
|
+
expect(line_item.promo_total).to eq(-10)
|
|
88
|
+
expect(line_item.adjustment_total).to eq(-9.5)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
it "tax linked to order" do
|
|
92
|
+
order_subject.update
|
|
93
|
+
order.reload
|
|
94
|
+
expect(order.included_tax_total).to eq(0)
|
|
95
|
+
expect(order.additional_tax_total).to eq(0.5)
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
context "best promotion is always applied" do
|
|
101
|
+
let(:calculator) { Calculator::FlatRate.new(preferred_amount: 10) }
|
|
102
|
+
|
|
103
|
+
let(:source) { Promotion::Actions::CreateItemAdjustments.create calculator: calculator }
|
|
104
|
+
|
|
105
|
+
def create_adjustment(label, amount)
|
|
106
|
+
create(:adjustment, order: order,
|
|
107
|
+
adjustable: line_item,
|
|
108
|
+
source: source,
|
|
109
|
+
amount: amount,
|
|
110
|
+
state: "closed",
|
|
111
|
+
label: label,
|
|
112
|
+
mandatory: false)
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
it "should make all but the most valuable promotion adjustment ineligible, " +
|
|
116
|
+
"leaving non promotion adjustments alone" do
|
|
117
|
+
create_adjustment("Promotion A", -100)
|
|
118
|
+
create_adjustment("Promotion B", -200)
|
|
119
|
+
create_adjustment("Promotion C", -300)
|
|
120
|
+
create(:adjustment, order: order,
|
|
121
|
+
adjustable: line_item,
|
|
122
|
+
source: nil,
|
|
123
|
+
amount: -500,
|
|
124
|
+
state: "closed",
|
|
125
|
+
label: "Some other credit")
|
|
126
|
+
line_item.adjustments.each { |a| a.update_column(:eligible, true) }
|
|
127
|
+
|
|
128
|
+
subject.update
|
|
129
|
+
|
|
130
|
+
expect(line_item.adjustments.promotion.eligible.count).to eq(1)
|
|
131
|
+
expect(line_item.adjustments.promotion.eligible.first.label).to eq('Promotion C')
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
it "should choose the most recent promotion adjustment when amounts are equal" do
|
|
135
|
+
# Using Timecop is a regression test
|
|
136
|
+
Timecop.freeze do
|
|
137
|
+
create_adjustment("Promotion A", -200)
|
|
138
|
+
create_adjustment("Promotion B", -200)
|
|
139
|
+
end
|
|
140
|
+
line_item.adjustments.each { |a| a.update_column(:eligible, true) }
|
|
141
|
+
|
|
142
|
+
subject.update
|
|
143
|
+
|
|
144
|
+
expect(line_item.adjustments.promotion.eligible.count).to eq(1)
|
|
145
|
+
expect(line_item.adjustments.promotion.eligible.first.label).to eq('Promotion B')
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
context "when previously ineligible promotions become available" do
|
|
149
|
+
let(:order_promo1) do
|
|
150
|
+
create(:promotion,
|
|
151
|
+
:with_order_adjustment,
|
|
152
|
+
:with_item_total_rule,
|
|
153
|
+
weighted_order_adjustment_amount: 5,
|
|
154
|
+
item_total_threshold_amount: 10)
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
let(:order_promo2) do
|
|
158
|
+
create(:promotion,
|
|
159
|
+
:with_order_adjustment,
|
|
160
|
+
:with_item_total_rule,
|
|
161
|
+
weighted_order_adjustment_amount: 10,
|
|
162
|
+
item_total_threshold_amount: 20)
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
let(:order_promos) { [order_promo1, order_promo2] }
|
|
166
|
+
|
|
167
|
+
let(:line_item_promo1) do
|
|
168
|
+
create(:promotion,
|
|
169
|
+
:with_line_item_adjustment,
|
|
170
|
+
:with_item_total_rule,
|
|
171
|
+
adjustment_rate: 2.5,
|
|
172
|
+
item_total_threshold_amount: 10)
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
let(:line_item_promo2) do
|
|
176
|
+
create(:promotion,
|
|
177
|
+
:with_line_item_adjustment,
|
|
178
|
+
:with_item_total_rule,
|
|
179
|
+
adjustment_rate: 5,
|
|
180
|
+
item_total_threshold_amount: 20)
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
let(:line_item_promos) { [line_item_promo1, line_item_promo2] }
|
|
184
|
+
let(:order) { create(:order_with_line_items, line_items_count: 1) }
|
|
185
|
+
|
|
186
|
+
# Apply promotions in different sequences. Results should be the same.
|
|
187
|
+
promo_sequences = [[0, 1], [1, 0]]
|
|
188
|
+
|
|
189
|
+
promo_sequences.each do |promo_sequence|
|
|
190
|
+
it "should pick the best order-level promo according to current eligibility" do
|
|
191
|
+
# apply both promos to the order, even though only promo1 is eligible
|
|
192
|
+
order_promos[promo_sequence[0]].activate order: order
|
|
193
|
+
order_promos[promo_sequence[1]].activate order: order
|
|
194
|
+
|
|
195
|
+
order.reload
|
|
196
|
+
msg = "Expected two adjustments (using sequence #{promo_sequence})"
|
|
197
|
+
expect(order.all_adjustments.count).to eq(2), msg
|
|
198
|
+
|
|
199
|
+
msg = "Expected one elegible adjustment (using sequence #{promo_sequence})"
|
|
200
|
+
expect(order.all_adjustments.eligible.count).to eq(1), msg
|
|
201
|
+
|
|
202
|
+
msg = "Expected promo1 to be used (using sequence #{promo_sequence})"
|
|
203
|
+
expect(order.all_adjustments.eligible.first.source.promotion).to eq(order_promo1), msg
|
|
204
|
+
|
|
205
|
+
order.contents.add create(:variant, price: 10), 1
|
|
206
|
+
order.save
|
|
207
|
+
|
|
208
|
+
order.reload
|
|
209
|
+
msg = "Expected two adjustments (using sequence #{promo_sequence})"
|
|
210
|
+
expect(order.all_adjustments.count).to eq(2), msg
|
|
211
|
+
|
|
212
|
+
msg = "Expected one elegible adjustment (using sequence #{promo_sequence})"
|
|
213
|
+
expect(order.all_adjustments.eligible.count).to eq(1), msg
|
|
214
|
+
|
|
215
|
+
msg = "Expected promo2 to be used (using sequence #{promo_sequence})"
|
|
216
|
+
expect(order.all_adjustments.eligible.first.source.promotion).to eq(order_promo2), msg
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
promo_sequences.each do |promo_sequence|
|
|
221
|
+
it "should pick the best line-item-level promo according to current eligibility" do
|
|
222
|
+
# apply both promos to the order, even though only promo1 is eligible
|
|
223
|
+
line_item_promos[promo_sequence[0]].activate order: order
|
|
224
|
+
line_item_promos[promo_sequence[1]].activate order: order
|
|
225
|
+
|
|
226
|
+
order.reload
|
|
227
|
+
msg = "Expected one adjustment (using sequence #{promo_sequence})"
|
|
228
|
+
expect(order.all_adjustments.count).to eq(1), msg
|
|
229
|
+
|
|
230
|
+
msg = "Expected one elegible adjustment (using sequence #{promo_sequence})"
|
|
231
|
+
expect(order.all_adjustments.eligible.count).to eq(1), msg
|
|
232
|
+
|
|
233
|
+
# line_item_promo1 is the only one that has thus far met the order total threshold,
|
|
234
|
+
# it is the only promo which should be applied.
|
|
235
|
+
msg = "Expected line_item_promo1 to be used (using sequence #{promo_sequence})"
|
|
236
|
+
expect(order.all_adjustments.first.source.promotion).to eq(line_item_promo1), msg
|
|
237
|
+
|
|
238
|
+
order.contents.add create(:variant, price: 10), 1
|
|
239
|
+
order.save
|
|
240
|
+
|
|
241
|
+
order.reload
|
|
242
|
+
msg = "Expected four adjustments (using sequence #{promo_sequence})"
|
|
243
|
+
expect(order.all_adjustments.count).to eq(4), msg
|
|
244
|
+
|
|
245
|
+
msg = "Expected two elegible adjustments (using sequence #{promo_sequence})"
|
|
246
|
+
expect(order.all_adjustments.eligible.count).to eq(2), msg
|
|
247
|
+
|
|
248
|
+
order.all_adjustments.eligible.each do |adjustment|
|
|
249
|
+
msg = "Expected line_item_promo2 to be used (using sequence #{promo_sequence})"
|
|
250
|
+
expect(adjustment.source.promotion).to eq(line_item_promo2), msg
|
|
251
|
+
end
|
|
252
|
+
end
|
|
253
|
+
end
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
context "multiple adjustments and the best one is not eligible" do
|
|
257
|
+
let!(:promo_a) { create_adjustment("Promotion A", -100) }
|
|
258
|
+
let!(:promo_c) { create_adjustment("Promotion C", -300) }
|
|
259
|
+
|
|
260
|
+
before do
|
|
261
|
+
promo_a.update_column(:eligible, true)
|
|
262
|
+
promo_c.update_column(:eligible, false)
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
# regression for #3274
|
|
266
|
+
it "still makes the previous best eligible adjustment valid" do
|
|
267
|
+
subject.update
|
|
268
|
+
expect(line_item.adjustments.promotion.eligible.first.label).to eq('Promotion A')
|
|
269
|
+
end
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
it "should only leave one adjustment even if 2 have the same amount" do
|
|
273
|
+
create_adjustment("Promotion A", -100)
|
|
274
|
+
create_adjustment("Promotion B", -200)
|
|
275
|
+
create_adjustment("Promotion C", -200)
|
|
276
|
+
|
|
277
|
+
subject.update
|
|
278
|
+
|
|
279
|
+
expect(line_item.adjustments.promotion.eligible.count).to eq(1)
|
|
280
|
+
expect(line_item.adjustments.promotion.eligible.first.amount.to_i).to eq(-200)
|
|
281
|
+
end
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
end
|
|
285
|
+
end
|
|
286
|
+
end
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
#
|
|
3
|
+
|
|
4
|
+
require 'spec_helper'
|
|
5
|
+
|
|
6
|
+
describe Spree::Adjustment, :type => :model do
|
|
7
|
+
|
|
8
|
+
let(:order) { Spree::Order.new }
|
|
9
|
+
|
|
10
|
+
before do
|
|
11
|
+
allow(order).to receive(:update!)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
let(:adjustment) { Spree::Adjustment.create!(label: 'Adjustment', adjustable: order, order: order, amount: 5) }
|
|
15
|
+
|
|
16
|
+
context '#create & #destroy' do
|
|
17
|
+
let(:adjustment) { Spree::Adjustment.new(label: "Adjustment", amount: 5, order: order, adjustable: create(:line_item)) }
|
|
18
|
+
|
|
19
|
+
it 'calls #update_adjustable_adjustment_total' do
|
|
20
|
+
expect(adjustment).to receive(:update_adjustable_adjustment_total).twice
|
|
21
|
+
adjustment.save
|
|
22
|
+
adjustment.destroy
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
context '#save' do
|
|
27
|
+
let(:order) { Spree::Order.create! }
|
|
28
|
+
let!(:adjustment) { Spree::Adjustment.create(label: "Adjustment", amount: 5, order: order, adjustable: order) }
|
|
29
|
+
|
|
30
|
+
it 'touches the adjustable' do
|
|
31
|
+
expect(adjustment.adjustable).to receive(:touch)
|
|
32
|
+
adjustment.amount = 3
|
|
33
|
+
adjustment.save
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
describe 'non_tax scope' do
|
|
38
|
+
subject do
|
|
39
|
+
Spree::Adjustment.non_tax.to_a
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
let!(:tax_adjustment) { create(:adjustment, order: order, source: create(:tax_rate)) }
|
|
43
|
+
let!(:non_tax_adjustment_with_source) { create(:adjustment, order: order, source_type: 'Spree::Order', source_id: nil) }
|
|
44
|
+
let!(:non_tax_adjustment_without_source) { create(:adjustment, order: order, source: nil) }
|
|
45
|
+
|
|
46
|
+
it 'select non-tax adjustments' do
|
|
47
|
+
expect(subject).to_not include tax_adjustment
|
|
48
|
+
expect(subject).to include non_tax_adjustment_with_source
|
|
49
|
+
expect(subject).to include non_tax_adjustment_without_source
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
describe 'competing_promos scope' do
|
|
54
|
+
before do
|
|
55
|
+
allow_any_instance_of(Spree::Adjustment).to receive(:update_adjustable_adjustment_total).and_return(true)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
subject do
|
|
59
|
+
Spree::Adjustment.competing_promos.to_a
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
let!(:promotion_adjustment) { create(:adjustment, order: order, source_type: 'Spree::PromotionAction', source_id: nil) }
|
|
63
|
+
let!(:custom_adjustment_with_source) { create(:adjustment, order: order, source_type: 'Custom', source_id: nil) }
|
|
64
|
+
let!(:non_promotion_adjustment_with_source) { create(:adjustment, order: order, source_type: 'Spree::Order', source_id: nil) }
|
|
65
|
+
let!(:non_promotion_adjustment_without_source) { create(:adjustment, order: order, source: nil) }
|
|
66
|
+
|
|
67
|
+
context 'no custom source_types have been added to competing_promos' do
|
|
68
|
+
before { Spree::Adjustment.competing_promos_source_types = ['Spree::PromotionAction'] }
|
|
69
|
+
|
|
70
|
+
it 'selects promotion adjustments by default' do
|
|
71
|
+
expect(subject).to include promotion_adjustment
|
|
72
|
+
expect(subject).to_not include custom_adjustment_with_source
|
|
73
|
+
expect(subject).to_not include non_promotion_adjustment_with_source
|
|
74
|
+
expect(subject).to_not include non_promotion_adjustment_without_source
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
context 'a custom source_type has been added to competing_promos' do
|
|
79
|
+
before { Spree::Adjustment.competing_promos_source_types = ['Spree::PromotionAction', 'Custom'] }
|
|
80
|
+
|
|
81
|
+
it 'selects adjustments with registered source_types' do
|
|
82
|
+
expect(subject).to include promotion_adjustment
|
|
83
|
+
expect(subject).to include custom_adjustment_with_source
|
|
84
|
+
expect(subject).to_not include non_promotion_adjustment_with_source
|
|
85
|
+
expect(subject).to_not include non_promotion_adjustment_without_source
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
context "adjustment state" do
|
|
92
|
+
let(:adjustment) { create(:adjustment, order: order, state: 'open') }
|
|
93
|
+
|
|
94
|
+
context "#closed?" do
|
|
95
|
+
it "is true when adjustment state is closed" do
|
|
96
|
+
adjustment.state = "closed"
|
|
97
|
+
expect(adjustment).to be_closed
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
it "is false when adjustment state is open" do
|
|
101
|
+
adjustment.state = "open"
|
|
102
|
+
expect(adjustment).to_not be_closed
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
context '#currency' do
|
|
108
|
+
it 'returns the globally configured currency' do
|
|
109
|
+
expect(adjustment.currency).to eq 'USD'
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
context "#display_amount" do
|
|
114
|
+
before { adjustment.amount = 10.55 }
|
|
115
|
+
|
|
116
|
+
it "shows the amount" do
|
|
117
|
+
expect(adjustment.display_amount.to_s).to eq "$10.55"
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
context "with currency set to JPY" do
|
|
121
|
+
context "when adjustable is set to an order" do
|
|
122
|
+
before do
|
|
123
|
+
expect(order).to receive(:currency).and_return('JPY')
|
|
124
|
+
adjustment.adjustable = order
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
it "displays in JPY" do
|
|
128
|
+
expect(adjustment.display_amount.to_s).to eq "¥11"
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
context "when adjustable is nil" do
|
|
133
|
+
it "displays in the default currency" do
|
|
134
|
+
expect(adjustment.display_amount.to_s).to eq "$10.55"
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
context '#update!' do
|
|
141
|
+
context "when adjustment is closed" do
|
|
142
|
+
before { expect(adjustment).to receive(:closed?).and_return(true) }
|
|
143
|
+
|
|
144
|
+
it "does not update the adjustment" do
|
|
145
|
+
expect(adjustment).to_not receive(:update_column)
|
|
146
|
+
adjustment.update!
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
context "when adjustment is open" do
|
|
151
|
+
before { expect(adjustment).to receive(:closed?).and_return(false) }
|
|
152
|
+
|
|
153
|
+
it "updates the amount" do
|
|
154
|
+
expect(adjustment).to receive(:adjustable).and_return(double("Adjustable")).at_least(1).times
|
|
155
|
+
expect(adjustment).to receive(:source).and_return(double("Source")).at_least(1).times
|
|
156
|
+
expect(adjustment.source).to receive("compute_amount").with(adjustment.adjustable).and_return(5)
|
|
157
|
+
expect(adjustment).to receive(:update_columns).with(amount: 5, updated_at: kind_of(Time))
|
|
158
|
+
adjustment.update!
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Spree::AppConfiguration, :type => :model do
|
|
4
|
+
|
|
5
|
+
let (:prefs) { Rails.application.config.spree.preferences }
|
|
6
|
+
|
|
7
|
+
it "should be available from the environment" do
|
|
8
|
+
prefs.layout = "my/layout"
|
|
9
|
+
expect(prefs.layout).to eq "my/layout"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it "should be available as Spree::Config for legacy access" do
|
|
13
|
+
Spree::Config.layout = "my/layout"
|
|
14
|
+
expect(Spree::Config.layout).to eq "my/layout"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "uses base searcher class by default" do
|
|
18
|
+
prefs.searcher_class = nil
|
|
19
|
+
expect(prefs.searcher_class).to eq Spree::Core::Search::Base
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end
|
|
23
|
+
|