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,243 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Spree
|
|
4
|
+
describe StockLocation, :type => :model do
|
|
5
|
+
subject { create(:stock_location_with_items, backorderable_default: true) }
|
|
6
|
+
let(:stock_item) { subject.stock_items.order(:id).first }
|
|
7
|
+
let(:variant) { stock_item.variant }
|
|
8
|
+
|
|
9
|
+
it 'creates stock_items for all variants' do
|
|
10
|
+
expect(subject.stock_items.count).to eq Variant.count
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
context "handling stock items" do
|
|
14
|
+
let!(:variant) { create(:variant) }
|
|
15
|
+
|
|
16
|
+
context "given a variant" do
|
|
17
|
+
subject { StockLocation.create(name: "testing", propagate_all_variants: false) }
|
|
18
|
+
|
|
19
|
+
context "set up" do
|
|
20
|
+
it "creates stock item" do
|
|
21
|
+
expect(subject).to receive(:propagate_variant)
|
|
22
|
+
subject.set_up_stock_item(variant)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
context "stock item exists" do
|
|
26
|
+
let!(:stock_item) { subject.propagate_variant(variant) }
|
|
27
|
+
|
|
28
|
+
it "returns existing stock item" do
|
|
29
|
+
expect(subject.set_up_stock_item(variant)).to eq(stock_item)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
context "propagate variants" do
|
|
35
|
+
let(:stock_item) { subject.propagate_variant(variant) }
|
|
36
|
+
|
|
37
|
+
it "creates a new stock item" do
|
|
38
|
+
expect {
|
|
39
|
+
subject.propagate_variant(variant)
|
|
40
|
+
}.to change{ StockItem.count }.by(1)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
context "passes backorderable default config" do
|
|
44
|
+
context "true" do
|
|
45
|
+
before { subject.backorderable_default = true }
|
|
46
|
+
it { expect(stock_item.backorderable).to be true }
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
context "false" do
|
|
50
|
+
before { subject.backorderable_default = false }
|
|
51
|
+
it { expect(stock_item.backorderable).to be false }
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
context "propagate all variants" do
|
|
57
|
+
subject { StockLocation.new(name: "testing") }
|
|
58
|
+
|
|
59
|
+
context "true" do
|
|
60
|
+
before { subject.propagate_all_variants = true }
|
|
61
|
+
|
|
62
|
+
specify do
|
|
63
|
+
expect(subject).to receive(:propagate_variant).at_least(:once)
|
|
64
|
+
subject.save!
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
context "false" do
|
|
69
|
+
before { subject.propagate_all_variants = false }
|
|
70
|
+
|
|
71
|
+
specify do
|
|
72
|
+
expect(subject).not_to receive(:propagate_variant)
|
|
73
|
+
subject.save!
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
it 'finds a stock_item for a variant' do
|
|
81
|
+
stock_item = subject.stock_item(variant)
|
|
82
|
+
expect(stock_item.count_on_hand).to eq 10
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
it 'finds a stock_item for a variant by id' do
|
|
86
|
+
stock_item = subject.stock_item(variant.id)
|
|
87
|
+
expect(stock_item.variant).to eq variant
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
it 'returns nil when stock_item is not found for variant' do
|
|
91
|
+
stock_item = subject.stock_item(100)
|
|
92
|
+
expect(stock_item).to be_nil
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
describe '#stock_item_or_create' do
|
|
96
|
+
before do
|
|
97
|
+
variant = create(:variant)
|
|
98
|
+
variant.stock_items.destroy_all
|
|
99
|
+
variant.save
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
it 'creates a stock_item if not found for a variant' do
|
|
103
|
+
stock_item = subject.stock_item_or_create(variant)
|
|
104
|
+
expect(stock_item.variant).to eq variant
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
it 'finds a count_on_hand for a variant' do
|
|
109
|
+
expect(subject.count_on_hand(variant)).to eq 10
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
it 'finds determines if you a variant is backorderable' do
|
|
113
|
+
expect(subject.backorderable?(variant)).to be true
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
it 'restocks a variant with a positive stock movement' do
|
|
117
|
+
originator = double
|
|
118
|
+
expect(subject).to receive(:move).with(variant, 5, originator)
|
|
119
|
+
subject.restock(variant, 5, originator)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
it 'unstocks a variant with a negative stock movement' do
|
|
123
|
+
originator = double
|
|
124
|
+
expect(subject).to receive(:move).with(variant, -5, originator)
|
|
125
|
+
subject.unstock(variant, 5, originator)
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
it 'it creates a stock_movement' do
|
|
129
|
+
expect {
|
|
130
|
+
subject.move variant, 5
|
|
131
|
+
}.to change { subject.stock_movements.where(stock_item_id: stock_item).count }.by(1)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
it 'can be deactivated' do
|
|
135
|
+
create(:stock_location, :active => true)
|
|
136
|
+
create(:stock_location, :active => false)
|
|
137
|
+
expect(Spree::StockLocation.active.count).to eq 1
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
it 'ensures only one stock location is default at a time' do
|
|
141
|
+
first = create(:stock_location, :active => true, :default => true)
|
|
142
|
+
second = create(:stock_location, :active => true, :default => true)
|
|
143
|
+
|
|
144
|
+
expect(first.reload.default).to eq false
|
|
145
|
+
expect(second.reload.default).to eq true
|
|
146
|
+
|
|
147
|
+
first.default = true
|
|
148
|
+
first.save!
|
|
149
|
+
|
|
150
|
+
expect(first.reload.default).to eq true
|
|
151
|
+
expect(second.reload.default).to eq false
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
context 'fill_status' do
|
|
155
|
+
it 'all on_hand with no backordered' do
|
|
156
|
+
on_hand, backordered = subject.fill_status(variant, 5)
|
|
157
|
+
expect(on_hand).to eq 5
|
|
158
|
+
expect(backordered).to eq 0
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
it 'some on_hand with some backordered' do
|
|
162
|
+
on_hand, backordered = subject.fill_status(variant, 20)
|
|
163
|
+
expect(on_hand).to eq 10
|
|
164
|
+
expect(backordered).to eq 10
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
it 'zero on_hand with all backordered' do
|
|
168
|
+
zero_stock_item = mock_model(StockItem,
|
|
169
|
+
count_on_hand: 0,
|
|
170
|
+
backorderable?: true)
|
|
171
|
+
expect(subject).to receive(:stock_item).with(variant).and_return(zero_stock_item)
|
|
172
|
+
|
|
173
|
+
on_hand, backordered = subject.fill_status(variant, 20)
|
|
174
|
+
expect(on_hand).to eq 0
|
|
175
|
+
expect(backordered).to eq 20
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
context 'when backordering is not allowed' do
|
|
179
|
+
before do
|
|
180
|
+
@stock_item = mock_model(StockItem, backorderable?: false)
|
|
181
|
+
expect(subject).to receive(:stock_item).with(variant).and_return(@stock_item)
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
it 'all on_hand' do
|
|
185
|
+
allow(@stock_item).to receive_messages(count_on_hand: 10)
|
|
186
|
+
|
|
187
|
+
on_hand, backordered = subject.fill_status(variant, 5)
|
|
188
|
+
expect(on_hand).to eq 5
|
|
189
|
+
expect(backordered).to eq 0
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
it 'some on_hand' do
|
|
193
|
+
allow(@stock_item).to receive_messages(count_on_hand: 10)
|
|
194
|
+
|
|
195
|
+
on_hand, backordered = subject.fill_status(variant, 20)
|
|
196
|
+
expect(on_hand).to eq 10
|
|
197
|
+
expect(backordered).to eq 0
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
it 'zero on_hand' do
|
|
201
|
+
allow(@stock_item).to receive_messages(count_on_hand: 0)
|
|
202
|
+
|
|
203
|
+
on_hand, backordered = subject.fill_status(variant, 20)
|
|
204
|
+
expect(on_hand).to eq 0
|
|
205
|
+
expect(backordered).to eq 0
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
context 'without stock_items' do
|
|
210
|
+
subject { create(:stock_location) }
|
|
211
|
+
let(:variant) { create(:base_variant) }
|
|
212
|
+
|
|
213
|
+
it 'zero on_hand and backordered' do
|
|
214
|
+
subject
|
|
215
|
+
variant.stock_items.destroy_all
|
|
216
|
+
on_hand, backordered = subject.fill_status(variant, 1)
|
|
217
|
+
expect(on_hand).to eq 0
|
|
218
|
+
expect(backordered).to eq 0
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
context '#state_text' do
|
|
224
|
+
context 'state is blank' do
|
|
225
|
+
subject { StockLocation.create(name: "testing", state: nil, state_name: 'virginia') }
|
|
226
|
+
specify { expect(subject.state_text).to eq('virginia') }
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
context 'both name and abbr is present' do
|
|
230
|
+
let(:state) { stub_model(Spree::State, name: 'virginia', abbr: 'va') }
|
|
231
|
+
subject { StockLocation.create(name: "testing", state: state, state_name: nil) }
|
|
232
|
+
specify { expect(subject.state_text).to eq('va') }
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
context 'only name is present' do
|
|
236
|
+
let(:state) { stub_model(Spree::State, name: 'virginia', abbr: nil) }
|
|
237
|
+
subject { StockLocation.create(name: "testing", state: state, state_name: nil) }
|
|
238
|
+
specify { expect(subject.state_text).to eq('virginia') }
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
end
|
|
243
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Spree::StockMovement, :type => :model do
|
|
4
|
+
let(:stock_location) { create(:stock_location_with_items) }
|
|
5
|
+
let(:stock_item) { stock_location.stock_items.order(:id).first }
|
|
6
|
+
subject { build(:stock_movement, stock_item: stock_item) }
|
|
7
|
+
|
|
8
|
+
it 'should belong to a stock item' do
|
|
9
|
+
expect(subject).to respond_to(:stock_item)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it 'is readonly unless new' do
|
|
13
|
+
subject.save
|
|
14
|
+
expect {
|
|
15
|
+
subject.save
|
|
16
|
+
}.to raise_error(ActiveRecord::ReadOnlyRecord)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it 'does not update count on hand when track inventory levels is false' do
|
|
20
|
+
Spree::Config[:track_inventory_levels] = false
|
|
21
|
+
subject.quantity = 1
|
|
22
|
+
subject.save
|
|
23
|
+
stock_item.reload
|
|
24
|
+
expect(stock_item.count_on_hand).to eq(10)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it 'does not update count on hand when variant inventory tracking is off' do
|
|
28
|
+
stock_item.variant.track_inventory = false
|
|
29
|
+
subject.quantity = 1
|
|
30
|
+
subject.save
|
|
31
|
+
stock_item.reload
|
|
32
|
+
expect(stock_item.count_on_hand).to eq(10)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
context "when quantity is negative" do
|
|
36
|
+
context "after save" do
|
|
37
|
+
it "should decrement the stock item count on hand" do
|
|
38
|
+
subject.quantity = -1
|
|
39
|
+
subject.save
|
|
40
|
+
stock_item.reload
|
|
41
|
+
expect(stock_item.count_on_hand).to eq(9)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
context "when quantity is positive" do
|
|
47
|
+
context "after save" do
|
|
48
|
+
it "should increment the stock item count on hand" do
|
|
49
|
+
subject.quantity = 1
|
|
50
|
+
subject.save
|
|
51
|
+
stock_item.reload
|
|
52
|
+
expect(stock_item.count_on_hand).to eq(11)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Spree
|
|
4
|
+
describe StockTransfer, :type => :model do
|
|
5
|
+
let(:destination_location) { create(:stock_location_with_items) }
|
|
6
|
+
let(:source_location) { create(:stock_location_with_items) }
|
|
7
|
+
let(:stock_item) { source_location.stock_items.order(:id).first }
|
|
8
|
+
let(:variant) { stock_item.variant }
|
|
9
|
+
|
|
10
|
+
subject { StockTransfer.create(reference: 'PO123') }
|
|
11
|
+
|
|
12
|
+
describe '#reference' do
|
|
13
|
+
subject { super().reference }
|
|
14
|
+
it { is_expected.to eq 'PO123' }
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
describe '#to_param' do
|
|
18
|
+
subject { super().to_param }
|
|
19
|
+
it { is_expected.to match /T\d+/ }
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it 'transfers variants between 2 locations' do
|
|
23
|
+
variants = { variant => 5 }
|
|
24
|
+
|
|
25
|
+
subject.transfer(source_location,
|
|
26
|
+
destination_location,
|
|
27
|
+
variants)
|
|
28
|
+
|
|
29
|
+
expect(source_location.count_on_hand(variant)).to eq 5
|
|
30
|
+
expect(destination_location.count_on_hand(variant)).to eq 5
|
|
31
|
+
|
|
32
|
+
expect(subject.source_location).to eq source_location
|
|
33
|
+
expect(subject.destination_location).to eq destination_location
|
|
34
|
+
|
|
35
|
+
expect(subject.source_movements.first.quantity).to eq -5
|
|
36
|
+
expect(subject.destination_movements.first.quantity).to eq 5
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it 'receive new inventory (from a vendor)' do
|
|
40
|
+
variants = { variant => 5 }
|
|
41
|
+
|
|
42
|
+
subject.receive(destination_location, variants)
|
|
43
|
+
|
|
44
|
+
expect(destination_location.count_on_hand(variant)).to eq 5
|
|
45
|
+
|
|
46
|
+
expect(subject.source_location).to be_nil
|
|
47
|
+
expect(subject.destination_location).to eq destination_location
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Spree::Store, :type => :model do
|
|
4
|
+
|
|
5
|
+
describe ".by_url" do
|
|
6
|
+
let!(:store) { create(:store, url: "website1.com\nwww.subdomain.com") }
|
|
7
|
+
let!(:store_2) { create(:store, url: 'freethewhales.com') }
|
|
8
|
+
|
|
9
|
+
it "should find stores by url" do
|
|
10
|
+
by_domain = Spree::Store.by_url('www.subdomain.com')
|
|
11
|
+
|
|
12
|
+
expect(by_domain).to include(store)
|
|
13
|
+
expect(by_domain).not_to include(store_2)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
describe '.current' do
|
|
18
|
+
# there is a default store created with the test_app rake task.
|
|
19
|
+
let!(:store_1) { Spree::Store.first || create(:store) }
|
|
20
|
+
|
|
21
|
+
let!(:store_2) { create(:store, default: false, url: 'www.subdomain.com') }
|
|
22
|
+
|
|
23
|
+
it 'should return default when no domain' do
|
|
24
|
+
expect(subject.class.current).to eql(store_1)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it 'should return store for domain' do
|
|
28
|
+
expect(subject.class.current('spreecommerce.com')).to eql(store_1)
|
|
29
|
+
expect(subject.class.current('www.subdomain.com')).to eql(store_2)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
describe ".default" do
|
|
34
|
+
let!(:store) { create(:store) }
|
|
35
|
+
let!(:store_2) { create(:store, default: true) }
|
|
36
|
+
|
|
37
|
+
it "should ensure there is a default if one doesn't exist yet" do
|
|
38
|
+
expect(store_2.default).to be true
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "should ensure there is only one default" do
|
|
42
|
+
[store, store_2].each(&:reload)
|
|
43
|
+
|
|
44
|
+
expect(Spree::Store.where(default: true).count).to eq(1)
|
|
45
|
+
expect(store_2.default).to be true
|
|
46
|
+
expect(store.default).not_to be true
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Spree::TaxCategory, :type => :model do
|
|
4
|
+
context 'default tax category' do
|
|
5
|
+
let(:tax_category) { create(:tax_category) }
|
|
6
|
+
let(:new_tax_category) { create(:tax_category) }
|
|
7
|
+
|
|
8
|
+
before do
|
|
9
|
+
tax_category.update_column(:is_default, true)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it "should undefault the previous default tax category" do
|
|
13
|
+
new_tax_category.update_attributes({:is_default => true})
|
|
14
|
+
expect(new_tax_category.is_default).to be true
|
|
15
|
+
|
|
16
|
+
tax_category.reload
|
|
17
|
+
expect(tax_category.is_default).to be false
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it "should undefault the previous default tax category except when updating the existing default tax category" do
|
|
21
|
+
tax_category.update_column(:description, "Updated description")
|
|
22
|
+
|
|
23
|
+
tax_category.reload
|
|
24
|
+
expect(tax_category.is_default).to be true
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Spree::TaxRate, :type => :model do
|
|
4
|
+
context "match" do
|
|
5
|
+
let(:order) { create(:order) }
|
|
6
|
+
let(:country) { create(:country) }
|
|
7
|
+
let(:tax_category) { create(:tax_category) }
|
|
8
|
+
let(:calculator) { Spree::Calculator::FlatRate.new }
|
|
9
|
+
|
|
10
|
+
it "should return an empty array when tax_zone is nil" do
|
|
11
|
+
allow(order).to receive_messages :tax_zone => nil
|
|
12
|
+
expect(Spree::TaxRate.match(order.tax_zone)).to eq([])
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
context "when no rate zones match the tax zone" do
|
|
16
|
+
before do
|
|
17
|
+
Spree::TaxRate.create(:amount => 1, :zone => create(:zone))
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
context "when there is no default tax zone" do
|
|
21
|
+
before do
|
|
22
|
+
@zone = create(:zone, :name => "Country Zone", :default_tax => false, :zone_members => [])
|
|
23
|
+
@zone.zone_members.create(:zoneable => country)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it "should return an empty array" do
|
|
27
|
+
allow(order).to receive_messages :tax_zone => @zone
|
|
28
|
+
expect(Spree::TaxRate.match(order.tax_zone)).to eq([])
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "should return the rate that matches the rate zone" do
|
|
32
|
+
rate = Spree::TaxRate.create(
|
|
33
|
+
:amount => 1,
|
|
34
|
+
:zone => @zone,
|
|
35
|
+
:tax_category => tax_category,
|
|
36
|
+
:calculator => calculator
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
allow(order).to receive_messages :tax_zone => @zone
|
|
40
|
+
expect(Spree::TaxRate.match(order.tax_zone)).to eq([rate])
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it "should return all rates that match the rate zone" do
|
|
44
|
+
rate1 = Spree::TaxRate.create(
|
|
45
|
+
:amount => 1,
|
|
46
|
+
:zone => @zone,
|
|
47
|
+
:tax_category => tax_category,
|
|
48
|
+
:calculator => calculator
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
rate2 = Spree::TaxRate.create(
|
|
52
|
+
:amount => 2,
|
|
53
|
+
:zone => @zone,
|
|
54
|
+
:tax_category => tax_category,
|
|
55
|
+
:calculator => Spree::Calculator::FlatRate.new
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
allow(order).to receive_messages :tax_zone => @zone
|
|
59
|
+
expect(Spree::TaxRate.match(order.tax_zone)).to match_array([rate1, rate2])
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
context "when the tax_zone is contained within a rate zone" do
|
|
63
|
+
before do
|
|
64
|
+
sub_zone = create(:zone, :name => "State Zone", :zone_members => [])
|
|
65
|
+
sub_zone.zone_members.create(:zoneable => create(:state, :country => country))
|
|
66
|
+
allow(order).to receive_messages :tax_zone => sub_zone
|
|
67
|
+
@rate = Spree::TaxRate.create(
|
|
68
|
+
:amount => 1,
|
|
69
|
+
:zone => @zone,
|
|
70
|
+
:tax_category => tax_category,
|
|
71
|
+
:calculator => calculator
|
|
72
|
+
)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
it "should return the rate zone" do
|
|
76
|
+
expect(Spree::TaxRate.match(order.tax_zone)).to eq([@rate])
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
context "when there is a default tax zone" do
|
|
82
|
+
before do
|
|
83
|
+
@zone = create(:zone, :name => "Country Zone", :default_tax => true, :zone_members => [])
|
|
84
|
+
@zone.zone_members.create(:zoneable => country)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
let(:included_in_price) { false }
|
|
88
|
+
let!(:rate) do
|
|
89
|
+
Spree::TaxRate.create(:amount => 1,
|
|
90
|
+
:zone => @zone,
|
|
91
|
+
:tax_category => tax_category,
|
|
92
|
+
:calculator => calculator,
|
|
93
|
+
:included_in_price => included_in_price)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
subject { Spree::TaxRate.match(order.tax_zone) }
|
|
97
|
+
|
|
98
|
+
context "when the order has the same tax zone" do
|
|
99
|
+
before do
|
|
100
|
+
allow(order).to receive_messages :tax_zone => @zone
|
|
101
|
+
allow(order).to receive_messages :tax_address => tax_address
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
let(:tax_address) { stub_model(Spree::Address) }
|
|
105
|
+
|
|
106
|
+
context "when the tax is not a VAT" do
|
|
107
|
+
it { is_expected.to eq([rate]) }
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
context "when the tax is a VAT" do
|
|
111
|
+
let(:included_in_price) { true }
|
|
112
|
+
it { is_expected.to eq([rate]) }
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
context "when the order has a different tax zone" do
|
|
117
|
+
before do
|
|
118
|
+
allow(order).to receive_messages :tax_zone => create(:zone, :name => "Other Zone")
|
|
119
|
+
allow(order).to receive_messages :tax_address => tax_address
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
context "when the order has a tax_address" do
|
|
123
|
+
let(:tax_address) { stub_model(Spree::Address) }
|
|
124
|
+
|
|
125
|
+
context "when the tax is a VAT" do
|
|
126
|
+
let(:included_in_price) { true }
|
|
127
|
+
# The rate should match in this instance because:
|
|
128
|
+
# 1) It's the default rate (and as such, a negative adjustment should apply)
|
|
129
|
+
it { is_expected.to eq([rate]) }
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
context "when the tax is not VAT" do
|
|
133
|
+
it "returns no tax rate" do
|
|
134
|
+
expect(subject).to be_empty
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
context "when the order does not have a tax_address" do
|
|
140
|
+
let(:tax_address) { nil}
|
|
141
|
+
|
|
142
|
+
context "when the tax is a VAT" do
|
|
143
|
+
let(:included_in_price) { true }
|
|
144
|
+
# The rate should match in this instance because:
|
|
145
|
+
# 1) The order has no tax address by this stage
|
|
146
|
+
# 2) With no tax address, it has no tax zone
|
|
147
|
+
# 3) Therefore, we assume the default tax zone
|
|
148
|
+
# 4) This default zone has a default tax rate.
|
|
149
|
+
it { is_expected.to eq([rate]) }
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
context "when the tax is not a VAT" do
|
|
153
|
+
it { is_expected.to be_empty }
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
context ".adjust" do
|
|
162
|
+
let(:order) { stub_model(Spree::Order) }
|
|
163
|
+
let(:tax_category_1) { stub_model(Spree::TaxCategory) }
|
|
164
|
+
let(:tax_category_2) { stub_model(Spree::TaxCategory) }
|
|
165
|
+
let(:rate_1) { stub_model(Spree::TaxRate, :tax_category => tax_category_1) }
|
|
166
|
+
let(:rate_2) { stub_model(Spree::TaxRate, :tax_category => tax_category_2) }
|
|
167
|
+
|
|
168
|
+
context "with line items" do
|
|
169
|
+
let(:line_item) do
|
|
170
|
+
stub_model(Spree::LineItem,
|
|
171
|
+
:price => 10.0,
|
|
172
|
+
:quantity => 1,
|
|
173
|
+
:tax_category => tax_category_1,
|
|
174
|
+
:variant => stub_model(Spree::Variant)
|
|
175
|
+
)
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
let(:line_items) { [line_item] }
|
|
179
|
+
|
|
180
|
+
before do
|
|
181
|
+
allow(Spree::TaxRate).to receive_messages :match => [rate_1, rate_2]
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
it "should apply adjustments for two tax rates to the order" do
|
|
185
|
+
expect(rate_1).to receive(:adjust)
|
|
186
|
+
expect(rate_2).not_to receive(:adjust)
|
|
187
|
+
Spree::TaxRate.adjust(order, line_items)
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
context "with shipments" do
|
|
192
|
+
let(:shipments) { [stub_model(Spree::Shipment, :cost => 10.0, :tax_category => tax_category_1)] }
|
|
193
|
+
|
|
194
|
+
before do
|
|
195
|
+
allow(Spree::TaxRate).to receive_messages :match => [rate_1, rate_2]
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
it "should apply adjustments for two tax rates to the order" do
|
|
199
|
+
expect(rate_1).to receive(:adjust)
|
|
200
|
+
expect(rate_2).not_to receive(:adjust)
|
|
201
|
+
Spree::TaxRate.adjust(order, shipments)
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
context "#adjust" do
|
|
207
|
+
before do
|
|
208
|
+
@country = create(:country)
|
|
209
|
+
@zone = create(:zone, :name => "Country Zone", :default_tax => true, :zone_members => [])
|
|
210
|
+
@zone.zone_members.create(:zoneable => @country)
|
|
211
|
+
@category = Spree::TaxCategory.create :name => "Taxable Foo"
|
|
212
|
+
@category2 = Spree::TaxCategory.create(:name => "Non Taxable")
|
|
213
|
+
@rate1 = Spree::TaxRate.create(
|
|
214
|
+
:amount => 0.10,
|
|
215
|
+
:calculator => Spree::Calculator::DefaultTax.create,
|
|
216
|
+
:tax_category => @category,
|
|
217
|
+
:zone => @zone
|
|
218
|
+
)
|
|
219
|
+
@rate2 = Spree::TaxRate.create(
|
|
220
|
+
:amount => 0.05,
|
|
221
|
+
:calculator => Spree::Calculator::DefaultTax.create,
|
|
222
|
+
:tax_category => @category,
|
|
223
|
+
:zone => @zone
|
|
224
|
+
)
|
|
225
|
+
@order = Spree::Order.create!
|
|
226
|
+
@taxable = create(:product, :tax_category => @category)
|
|
227
|
+
@nontaxable = create(:product, :tax_category => @category2)
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
context "not taxable line item " do
|
|
231
|
+
let!(:line_item) { @order.contents.add(@nontaxable.master, 1) }
|
|
232
|
+
|
|
233
|
+
it "should not create a tax adjustment" do
|
|
234
|
+
Spree::TaxRate.adjust(@order, @order.line_items)
|
|
235
|
+
expect(line_item.adjustments.tax.charge.count).to eq(0)
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
it "should not create a refund" do
|
|
239
|
+
Spree::TaxRate.adjust(@order, @order.line_items)
|
|
240
|
+
expect(line_item.adjustments.credit.count).to eq(0)
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
context "taxable line item" do
|
|
245
|
+
let!(:line_item) { @order.contents.add(@taxable.master, 1) }
|
|
246
|
+
|
|
247
|
+
context "when price includes tax" do
|
|
248
|
+
before do
|
|
249
|
+
@rate1.update_column(:included_in_price, true)
|
|
250
|
+
@rate2.update_column(:included_in_price, true)
|
|
251
|
+
Spree::TaxRate.store_pre_tax_amount(line_item, [@rate1, @rate2])
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
context "when zone is contained by default tax zone" do
|
|
255
|
+
it "should create two adjustments, one for each tax rate" do
|
|
256
|
+
Spree::TaxRate.adjust(@order, @order.line_items)
|
|
257
|
+
expect(line_item.adjustments.count).to eq(1)
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
it "should not create a tax refund" do
|
|
261
|
+
Spree::TaxRate.adjust(@order, @order.line_items)
|
|
262
|
+
expect(line_item.adjustments.credit.count).to eq(0)
|
|
263
|
+
end
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
context "when order's zone is neither the default zone, or included in the default zone, but matches the rate's zone" do
|
|
267
|
+
before do
|
|
268
|
+
# With no zone members, this zone will not contain anything
|
|
269
|
+
# Previously:
|
|
270
|
+
# Zone.stub_chain :default_tax, :contains? => false
|
|
271
|
+
@zone.zone_members.delete_all
|
|
272
|
+
end
|
|
273
|
+
it "should create an adjustment" do
|
|
274
|
+
Spree::TaxRate.adjust(@order, @order.line_items)
|
|
275
|
+
expect(line_item.adjustments.charge.count).to eq(1)
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
it "should not create a tax refund for each tax rate" do
|
|
279
|
+
Spree::TaxRate.adjust(@order, @order.line_items)
|
|
280
|
+
expect(line_item.adjustments.credit.count).to eq(0)
|
|
281
|
+
end
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
context "when order's zone does not match default zone, is not included in the default zone, AND does not match the rate's zone" do
|
|
285
|
+
before do
|
|
286
|
+
@new_zone = create(:zone, :name => "New Zone", :default_tax => false)
|
|
287
|
+
@new_country = create(:country, :name => "New Country")
|
|
288
|
+
@new_zone.zone_members.create(:zoneable => @new_country)
|
|
289
|
+
@order.ship_address = create(:address, :country => @new_country)
|
|
290
|
+
@order.save
|
|
291
|
+
@order.reload
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
it "should not create positive adjustments" do
|
|
295
|
+
Spree::TaxRate.adjust(@order, @order.line_items)
|
|
296
|
+
expect(line_item.adjustments.charge.count).to eq(0)
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
it "should create a tax refund for each tax rate" do
|
|
300
|
+
Spree::TaxRate.adjust(@order, @order.line_items)
|
|
301
|
+
expect(line_item.adjustments.credit.count).to eq(1)
|
|
302
|
+
end
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
context "when price does not include tax" do
|
|
306
|
+
before do
|
|
307
|
+
allow(@order).to receive_messages :tax_zone => @zone
|
|
308
|
+
[@rate1, @rate2].each do |rate|
|
|
309
|
+
rate.included_in_price = false
|
|
310
|
+
rate.zone = @zone
|
|
311
|
+
rate.save
|
|
312
|
+
end
|
|
313
|
+
Spree::TaxRate.adjust(@order, @order.line_items)
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
it "should delete adjustments for open order when taxrate is deleted" do
|
|
317
|
+
@rate1.destroy!
|
|
318
|
+
@rate2.destroy!
|
|
319
|
+
expect(line_item.adjustments.count).to eq(0)
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
it "should not delete adjustments for complete order when taxrate is deleted" do
|
|
323
|
+
@order.update_column :completed_at, Time.now
|
|
324
|
+
@rate1.destroy!
|
|
325
|
+
@rate2.destroy!
|
|
326
|
+
expect(line_item.adjustments.count).to eq(2)
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
it "should create an adjustment" do
|
|
330
|
+
expect(line_item.adjustments.count).to eq(2)
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
it "should not create a tax refund" do
|
|
334
|
+
expect(line_item.adjustments.credit.count).to eq(0)
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
describe 'tax adjustments' do
|
|
338
|
+
before { Spree::TaxRate.adjust(@order, @order.line_items) }
|
|
339
|
+
|
|
340
|
+
it "should apply adjustments when a tax zone is present" do
|
|
341
|
+
expect(line_item.adjustments.count).to eq(2)
|
|
342
|
+
line_item.adjustments.each do |adjustment|
|
|
343
|
+
expect(adjustment.label).to eq("#{adjustment.source.tax_category.name} #{adjustment.source.amount * 100}%")
|
|
344
|
+
end
|
|
345
|
+
end
|
|
346
|
+
|
|
347
|
+
describe 'when the tax zone is removed' do
|
|
348
|
+
before { allow(@order).to receive_messages :tax_zone => nil }
|
|
349
|
+
|
|
350
|
+
it 'does not apply any adjustments' do
|
|
351
|
+
Spree::TaxRate.adjust(@order, @order.line_items)
|
|
352
|
+
expect(line_item.adjustments.count).to eq(0)
|
|
353
|
+
end
|
|
354
|
+
end
|
|
355
|
+
end
|
|
356
|
+
end
|
|
357
|
+
|
|
358
|
+
context "when two rates apply" do
|
|
359
|
+
before do
|
|
360
|
+
@price_before_taxes = line_item.price / (1 + @rate1.amount + @rate2.amount)
|
|
361
|
+
# Use the same rounding method as in DefaultTax calculator
|
|
362
|
+
@price_before_taxes = BigDecimal.new(@price_before_taxes).round(2, BigDecimal::ROUND_HALF_UP)
|
|
363
|
+
line_item.update_column(:pre_tax_amount, @price_before_taxes)
|
|
364
|
+
# Clear out any previously automatically-applied adjustments
|
|
365
|
+
@order.all_adjustments.delete_all
|
|
366
|
+
@rate1.adjust(@order, line_item)
|
|
367
|
+
@rate2.adjust(@order, line_item)
|
|
368
|
+
end
|
|
369
|
+
|
|
370
|
+
it "should create two price adjustments" do
|
|
371
|
+
expect(@order.line_item_adjustments.count).to eq(2)
|
|
372
|
+
end
|
|
373
|
+
|
|
374
|
+
it "price adjustments should be accurate" do
|
|
375
|
+
included_tax = @order.line_item_adjustments.sum(:amount)
|
|
376
|
+
expect(@price_before_taxes + included_tax).to eq(line_item.price)
|
|
377
|
+
end
|
|
378
|
+
end
|
|
379
|
+
end
|
|
380
|
+
end
|
|
381
|
+
end
|
|
382
|
+
end
|