solidus_core 1.3.0.beta1 → 1.3.0.rc1

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.

Potentially problematic release.


This version of solidus_core might be problematic. Click here for more details.

Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/app/assets/images/noimage/large.png +0 -0
  4. data/app/assets/images/noimage/mini.png +0 -0
  5. data/app/assets/images/noimage/product.png +0 -0
  6. data/app/assets/images/noimage/small.png +0 -0
  7. data/app/models/spree/app_configuration.rb +9 -9
  8. data/app/models/spree/country.rb +1 -0
  9. data/app/models/spree/line_item.rb +7 -1
  10. data/app/models/spree/payment_method.rb +1 -1
  11. data/app/models/spree/preferences/preferable.rb +1 -0
  12. data/app/models/spree/preferences/statically_configurable.rb +2 -2
  13. data/app/models/spree/price.rb +30 -2
  14. data/app/models/spree/product.rb +4 -1
  15. data/app/models/spree/stock/inventory_unit_builder.rb +2 -2
  16. data/app/models/spree/tax/tax_location.rb +4 -0
  17. data/app/models/spree/tax_rate.rb +2 -11
  18. data/app/models/spree/variant/price_selector.rb +35 -0
  19. data/app/models/spree/variant/pricing_options.rb +69 -4
  20. data/app/models/spree/variant/vat_price_generator.rb +58 -0
  21. data/app/models/spree/variant.rb +38 -16
  22. data/config/locales/en.yml +22 -1
  23. data/db/migrate/20140410141842_add_many_missing_indexes.rb +15 -13
  24. data/db/migrate/20140410150358_correct_some_polymorphic_index_and_add_more_missing.rb +40 -38
  25. data/db/migrate/20141217215630_update_product_slug_index.rb +4 -2
  26. data/db/migrate/20150723224133_remove_unnecessary_indexes.rb +2 -10
  27. data/db/migrate/20151219020209_add_stock_item_unique_index.rb +2 -2
  28. data/db/migrate/20160509181311_add_country_iso_to_prices.rb +8 -0
  29. data/lib/spree/core/class_constantizer.rb +31 -0
  30. data/lib/spree/core/engine.rb +55 -59
  31. data/lib/spree/core/environment/calculators.rb +6 -1
  32. data/lib/spree/core/environment.rb +5 -2
  33. data/lib/spree/core/environment_extension.rb +16 -12
  34. data/lib/spree/core/price_migrator.rb +32 -0
  35. data/lib/spree/core/search/base.rb +2 -2
  36. data/lib/spree/core/version.rb +1 -1
  37. data/lib/spree/core.rb +4 -0
  38. data/lib/spree/migration_helpers.rb +19 -0
  39. data/lib/spree/money.rb +41 -15
  40. data/lib/spree/promo/environment.rb +2 -1
  41. data/lib/spree/testing_support/controller_requests.rb +22 -7
  42. data/lib/spree/testing_support/factories/state_factory.rb +7 -0
  43. data/lib/spree/testing_support/factories/stock_location_factory.rb +4 -1
  44. data/lib/tasks/migrations/create_vat_prices.rake +11 -0
  45. data/lib/tasks/upgrade.rake +2 -1
  46. data/spec/lib/spree/core/class_constantizer_spec.rb +68 -0
  47. data/spec/lib/spree/core/environment_extension_spec.rb +33 -0
  48. data/spec/lib/spree/core/price_migrator_spec.rb +356 -0
  49. data/spec/lib/spree/core/testing_support/factories/state_factory_spec.rb +9 -0
  50. data/spec/lib/spree/core/testing_support/factories/stock_location_factory_spec.rb +9 -0
  51. data/spec/lib/spree/money_spec.rb +75 -0
  52. data/spec/models/spree/app_configuration_spec.rb +5 -5
  53. data/spec/models/spree/country_spec.rb +16 -0
  54. data/spec/models/spree/line_item_spec.rb +6 -2
  55. data/spec/models/spree/preferences/preferable_spec.rb +5 -0
  56. data/spec/models/spree/preferences/statically_configurable_spec.rb +4 -0
  57. data/spec/models/spree/price_spec.rb +89 -0
  58. data/spec/models/spree/stock/coordinator_spec.rb +9 -0
  59. data/spec/models/spree/stock/splitter/shipping_category_spec.rb +30 -32
  60. data/spec/models/spree/tax/tax_location_spec.rb +14 -5
  61. data/spec/models/spree/tax/taxation_integration_spec.rb +15 -42
  62. data/spec/models/spree/variant/{pricer_spec.rb → price_selector_spec.rb} +41 -1
  63. data/spec/models/spree/variant/pricing_options_spec.rb +87 -4
  64. data/spec/models/spree/variant/vat_price_generator_spec.rb +69 -0
  65. data/spec/models/spree/variant_spec.rb +57 -8
  66. metadata +14 -5
  67. data/app/models/spree/product_scope/scopes.rb +0 -47
  68. data/app/models/spree/variant/pricer.rb +0 -19
@@ -1,21 +1,36 @@
1
1
  module Spree
2
2
  module TestingSupport
3
- # Use this module to easily test Spree actions within Spree components or
4
- # inside your application to test routes for the mounted Spree engine.
3
+ # A module providing convenience methods to test Solidus controllers
4
+ # in Rails controller/functional tests. Possibly from inside an
5
+ # application with a mounted Solidus engine.
5
6
  #
6
- # Inside your spec_helper.rb, include this module inside the
7
- # RSpec.configure block by doing this:
7
+ # *There is generaly no need* to use this module. Instead, in
8
+ # a functional/controller test against a Spree controller, just
9
+ # use standard Rails functionality by including:
10
+ #
11
+ # routes { Spree::Core::Engine.routes }
12
+ #
13
+ # And then use standard Rails test `get`, `post` etc methods.
14
+ #
15
+ # But some legacy code uses this ControllerRequests helper. It must
16
+ # be included only in tests against Spree controllers, it will interfere
17
+ # with tests against local app or other engine controllers, resulting
18
+ # in ActionController::UrlGenerationError.
19
+ #
20
+ # To use this module, inside your spec_helper.rb, include this module inside
21
+ # the RSpec.configure block by:
8
22
  #
9
23
  # require 'spree/testing_support/controller_requests'
10
24
  # RSpec.configure do |c|
11
- # c.include Spree::TestingSupport::ControllerRequests, :type => :controller
25
+ # c.include Spree::TestingSupport::ControllerRequests, spree_controller: true
12
26
  # end
13
27
  #
14
- # Then, in your controller tests, you can access spree routes like this:
28
+ # Then, in your controller tests against spree controllers, you can access
29
+ # tag to use this module, and access spree routes like this:
15
30
  #
16
31
  # require 'spec_helper'
17
32
  #
18
- # describe Spree::ProductsController do
33
+ # describe Spree::ProductsController, :spree_controller do
19
34
  # it "can see all the products" do
20
35
  # spree_get :index
21
36
  # end
@@ -8,6 +8,13 @@ FactoryGirl.define do
8
8
 
9
9
  carmen_subregion do
10
10
  carmen_country = Carmen::Country.coded(country.iso)
11
+
12
+ # TODO: This condition can be removed after this carmen update is
13
+ # available: https://github.com/jim/carmen/pull/177
14
+ if !carmen_country.subregions?
15
+ fail("Country #{country.iso} has no subregions")
16
+ end
17
+
11
18
  carmen_country.subregions.coded(state_code) ||
12
19
  carmen_country.subregions.sort_by(&:name).first ||
13
20
  fail("Country #{country.iso} has no subregions")
@@ -14,7 +14,10 @@ FactoryGirl.define do
14
14
 
15
15
  country { |stock_location| Spree::Country.first || stock_location.association(:country) }
16
16
  state do |stock_location|
17
- stock_location.country.states.first || stock_location.association(:state, country: stock_location.country)
17
+ carmen_country = Carmen::Country.coded(stock_location.country.iso)
18
+ if carmen_country.subregions?
19
+ stock_location.country.states.first || stock_location.association(:state, country: stock_location.country)
20
+ end
18
21
  end
19
22
 
20
23
  factory :stock_location_without_variant_propagation do
@@ -0,0 +1,11 @@
1
+ namespace :solidus do
2
+ namespace :migrations do
3
+ namespace :create_vat_prices do
4
+ task up: :environment do
5
+ print "Creating differentiated prices for VAT countries ... "
6
+ Spree::PriceMigrator.migrate_default_vat_prices
7
+ puts "Success."
8
+ end
9
+ end
10
+ end
11
+ end
@@ -3,7 +3,8 @@ namespace :solidus do
3
3
  desc "Upgrade Solidus to version 1.3"
4
4
  task one_point_three: [
5
5
  'solidus:migrations:assure_store_on_orders:up',
6
- 'solidus:migrations:migrate_shipping_rate_taxes:up'
6
+ 'solidus:migrations:migrate_shipping_rate_taxes:up',
7
+ 'solidus:migrations:create_vat_prices'
7
8
  ] do
8
9
  puts "Your Solidus install is ready for Solidus 1.3."
9
10
  end
@@ -0,0 +1,68 @@
1
+ require 'spec_helper'
2
+
3
+ module ClassConstantizerTest
4
+ ClassA = Class.new
5
+ ClassB = Class.new
6
+
7
+ def self.reload
8
+ [:ClassA, :ClassB].each do |klass|
9
+ remove_const(klass)
10
+ const_set(klass, Class.new)
11
+ end
12
+ end
13
+ end
14
+
15
+ describe Spree::Core::ClassConstantizer::Set do
16
+ let(:set) { described_class.new }
17
+
18
+ describe "#concat" do
19
+ it "can add one item" do
20
+ set.concat(['ClassConstantizerTest::ClassA'])
21
+ expect(set).to include(ClassConstantizerTest::ClassA)
22
+ end
23
+
24
+ it "can add two items" do
25
+ set.concat(['ClassConstantizerTest::ClassA', ClassConstantizerTest::ClassB])
26
+ expect(set).to include(ClassConstantizerTest::ClassA)
27
+ expect(set).to include(ClassConstantizerTest::ClassB)
28
+ end
29
+ end
30
+
31
+ describe "<<" do
32
+ it "can add by string" do
33
+ set << "ClassConstantizerTest::ClassA"
34
+ expect(set).to include(ClassConstantizerTest::ClassA)
35
+ end
36
+
37
+ it "can add by class" do
38
+ set << ClassConstantizerTest::ClassA
39
+ expect(set).to include(ClassConstantizerTest::ClassA)
40
+ end
41
+
42
+ describe "class redefinition" do
43
+ shared_examples "working code reloading" do
44
+ it "works with a class" do
45
+ original = ClassConstantizerTest::ClassA
46
+
47
+ ClassConstantizerTest.reload
48
+
49
+ # Sanity check
50
+ expect(original).not_to eq(ClassConstantizerTest::ClassA)
51
+
52
+ expect(set).to include(ClassConstantizerTest::ClassA)
53
+ expect(set).to_not include(original)
54
+ end
55
+ end
56
+
57
+ context "with a class" do
58
+ before { set << ClassConstantizerTest::ClassA }
59
+ it_should_behave_like "working code reloading"
60
+ end
61
+
62
+ context "with a string" do
63
+ before { set << "ClassConstantizerTest::ClassA" }
64
+ it_should_behave_like "working code reloading"
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+ class DummyClass
4
+ include Spree::Core::EnvironmentExtension
5
+ end
6
+
7
+ class C1; end
8
+ class C2; end
9
+ class C3; end
10
+
11
+ describe Spree::Core::EnvironmentExtension do
12
+ subject { DummyClass.new }
13
+
14
+ before { subject.add_class('random_name') }
15
+
16
+ describe 'Basis' do
17
+ it { respond_to?(:random_name) }
18
+ it { respond_to?(:random_name=) }
19
+ end
20
+
21
+ describe '#getter' do
22
+ it { expect(subject.random_name).to be_empty }
23
+ it { expect(subject.random_name).to be_kind_of Spree::Core::ClassConstantizer::Set }
24
+ end
25
+
26
+ describe '#setter' do
27
+ before { subject.random_name = [C1, C2]; @set = subject.random_name.to_a }
28
+
29
+ it { expect(@set).to include(C1) }
30
+ it { expect(@set).to include(C2) }
31
+ it { expect(@set).not_to include(C3) }
32
+ end
33
+ end
@@ -0,0 +1,356 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::PriceMigrator do
4
+ let(:order) { create :order, ship_address: shipping_address, state: "delivery" }
5
+ let(:book_product) do
6
+ create :product,
7
+ price: 20,
8
+ name: "Book",
9
+ tax_category: books_category,
10
+ shipping_category: books_shipping_category
11
+ end
12
+ let(:download_product) do
13
+ create :product,
14
+ price: 10,
15
+ name: "Download",
16
+ tax_category: digital_category,
17
+ shipping_category: digital_shipping_category
18
+ end
19
+ let(:sweater_product) do
20
+ create :product,
21
+ price: 30,
22
+ name: "Download",
23
+ tax_category: normal_category,
24
+ shipping_category: normal_shipping_category
25
+ end
26
+
27
+ let!(:book) { book_product.master }
28
+ let!(:download) { download_product.master }
29
+ let!(:sweater) { sweater_product.master }
30
+
31
+ let(:books_category) { create :tax_category, name: "Books" }
32
+ let(:normal_category) { create :tax_category, name: "Normal" }
33
+ let(:digital_category) { create :tax_category, name: "Digital Goods" }
34
+
35
+ let(:books_shipping_category) { create :shipping_category, name: "Book Shipping" }
36
+ let(:normal_shipping_category) { create :shipping_category, name: "Normal Shipping" }
37
+ let(:digital_shipping_category) { create :shipping_category, name: "Digital Premium Download" }
38
+
39
+ let(:line_item) { order.line_items.first }
40
+ let(:shipment) { order.shipments.first }
41
+ let(:shipping_rate) { shipment.shipping_rates.first }
42
+
43
+ context 'selling from germany' do
44
+ let(:germany) { create :country, iso: "DE" }
45
+ # The weird default_tax boolean is what makes this context one with default included taxes
46
+ let!(:germany_zone) { create :zone, countries: [germany], default_tax: true }
47
+ let(:romania) { create(:country, iso: "RO") }
48
+ let(:romania_zone) { create(:zone, countries: [romania] ) }
49
+ let(:eu_zone) { create(:zone, countries: [romania, germany]) }
50
+ let(:world_zone) { create(:zone, :with_country) }
51
+
52
+ let!(:german_book_vat) do
53
+ create(
54
+ :tax_rate,
55
+ name: "German reduced VAT",
56
+ included_in_price: true,
57
+ amount: 0.07,
58
+ tax_category: books_category,
59
+ zone: eu_zone
60
+ )
61
+ end
62
+ let!(:german_normal_vat) do
63
+ create(
64
+ :tax_rate,
65
+ name: "German VAT",
66
+ included_in_price: true,
67
+ amount: 0.19,
68
+ tax_category: normal_category,
69
+ zone: eu_zone
70
+ )
71
+ end
72
+ let!(:german_digital_vat) do
73
+ create(
74
+ :tax_rate,
75
+ name: "German VAT",
76
+ included_in_price: true,
77
+ amount: 0.19,
78
+ tax_category: digital_category,
79
+ zone: germany_zone
80
+ )
81
+ end
82
+ let!(:romanian_digital_vat) do
83
+ create(
84
+ :tax_rate,
85
+ name: "Romanian VAT",
86
+ included_in_price: true,
87
+ amount: 0.24,
88
+ tax_category: digital_category,
89
+ zone: romania_zone
90
+ )
91
+ end
92
+ let!(:book_shipping_method) do
93
+ create :shipping_method,
94
+ cost: 8.00,
95
+ shipping_categories: [books_shipping_category],
96
+ tax_category: books_category,
97
+ zones: [eu_zone, world_zone]
98
+ end
99
+
100
+ let!(:sweater_shipping_method) do
101
+ create :shipping_method,
102
+ cost: 16.00,
103
+ shipping_categories: [normal_shipping_category],
104
+ tax_category: normal_category,
105
+ zones: [eu_zone, world_zone]
106
+ end
107
+
108
+ let!(:premium_download_shipping_method) do
109
+ create :shipping_method,
110
+ cost: 2.00,
111
+ shipping_categories: [digital_shipping_category],
112
+ tax_category: digital_category,
113
+ zones: [eu_zone, world_zone]
114
+ end
115
+
116
+ before do
117
+ Spree::PriceMigrator.migrate_default_vat_prices
118
+ order.contents.add(variant)
119
+ end
120
+
121
+ context 'to germany' do
122
+ let(:shipping_address) { create :address, country_iso_code: "DE" }
123
+
124
+ context 'an order with a book' do
125
+ let(:variant) { book }
126
+
127
+ it 'still has the original price' do
128
+ expect(line_item.price).to eq(20)
129
+ end
130
+
131
+ it 'has one tax adjustment' do
132
+ expect(line_item.adjustments.tax.count).to eq(1)
133
+ end
134
+
135
+ it 'has 1.13 cents of included tax' do
136
+ expect(line_item.included_tax_total).to eq(1.31)
137
+ end
138
+ end
139
+
140
+ context 'an order with a sweater' do
141
+ let(:variant) { sweater }
142
+
143
+ it 'still has the original price' do
144
+ expect(line_item.price).to eq(30)
145
+ end
146
+
147
+ it 'has one tax adjustment' do
148
+ expect(line_item.adjustments.tax.count).to eq(1)
149
+ end
150
+
151
+ it 'has 4,78 of included tax' do
152
+ expect(line_item.included_tax_total).to eq(4.79)
153
+ end
154
+ end
155
+
156
+ context 'an order with a download' do
157
+ let(:variant) { download }
158
+
159
+ it 'still has the original price' do
160
+ expect(line_item.price).to eq(10)
161
+ end
162
+
163
+ it 'has one tax adjustment' do
164
+ expect(line_item.adjustments.tax.count).to eq(1)
165
+ end
166
+
167
+ it 'has 1.60 of included tax' do
168
+ expect(line_item.included_tax_total).to eq(1.60)
169
+ end
170
+ end
171
+ end
172
+
173
+ context 'to romania' do
174
+ let(:shipping_address) { create :address, country_iso_code: "RO" }
175
+
176
+ context 'an order with a book' do
177
+ let(:variant) { book }
178
+
179
+ it 'still has the original price' do
180
+ expect(line_item.price).to eq(20)
181
+ end
182
+
183
+ it 'is adjusted to the original price' do
184
+ expect(line_item.total).to eq(20)
185
+ end
186
+
187
+ it 'has one tax adjustment' do
188
+ expect(line_item.adjustments.tax.count).to eq(1)
189
+ end
190
+
191
+ it 'has 1.13 cents of included tax' do
192
+ expect(line_item.included_tax_total).to eq(1.31)
193
+ end
194
+
195
+ it 'has a constant amount pre tax' do
196
+ expect(line_item.discounted_amount - line_item.included_tax_total).to eq(18.69)
197
+ end
198
+ end
199
+
200
+ context 'an order with a sweater' do
201
+ let(:variant) { sweater }
202
+
203
+ it 'still has the original price' do
204
+ expect(line_item.price).to eq(30)
205
+ end
206
+
207
+ it 'has one tax adjustment' do
208
+ expect(line_item.adjustments.tax.count).to eq(1)
209
+ end
210
+
211
+ it 'has 4.79 of included tax' do
212
+ expect(line_item.included_tax_total).to eq(4.79)
213
+ end
214
+
215
+ it 'has a constant amount pre tax' do
216
+ expect(line_item.discounted_amount - line_item.included_tax_total).to eq(25.21)
217
+ end
218
+ end
219
+
220
+ context 'an order with a download' do
221
+ let(:variant) { download }
222
+
223
+ it 'still has an adjusted price for romania' do
224
+ expect(line_item.price).to eq(10.42)
225
+ end
226
+
227
+ it 'has one tax adjustment' do
228
+ expect(line_item.adjustments.tax.count).to eq(1)
229
+ end
230
+
231
+ it 'has 2.02 of included tax' do
232
+ expect(line_item.included_tax_total).to eq(2.02)
233
+ end
234
+
235
+ it 'has a constant amount pre tax' do
236
+ expect(line_item.discounted_amount - line_item.included_tax_total).to eq(8.40)
237
+ end
238
+ end
239
+ end
240
+
241
+ # Technically, this can't be the case yet as the order won't pass the shipment stage,
242
+ # but the taxation code shouldn't implicitly depend on the shipping code.
243
+ context 'to an address that does not have a zone associated' do
244
+ let(:shipping_address) { create :address, country_iso_code: "IT" }
245
+
246
+ context 'an order with a book' do
247
+ let(:variant) { book }
248
+
249
+ it 'should sell at the net price' do
250
+ expect(line_item.price).to eq(18.69)
251
+ end
252
+
253
+ it 'is adjusted to the net price' do
254
+ expect(line_item.total).to eq(18.69)
255
+ end
256
+
257
+ it 'has no tax adjustments' do
258
+ expect(line_item.adjustments.tax.count).to eq(0)
259
+ end
260
+
261
+ it 'has no included tax' do
262
+ expect(line_item.included_tax_total).to eq(0)
263
+ end
264
+
265
+ it 'has no additional tax' do
266
+ expect(line_item.additional_tax_total).to eq(0)
267
+ end
268
+
269
+ it 'has a constant amount pre tax' do
270
+ expect(line_item.discounted_amount - line_item.included_tax_total).to eq(18.69)
271
+ end
272
+ end
273
+ end
274
+
275
+ # International delivery, no tax applies whatsoever
276
+ context 'to anywhere else in the world' do
277
+ let(:shipping_address) { create :address, country: world_zone.countries.first }
278
+
279
+ context 'an order with a book' do
280
+ let(:variant) { book }
281
+
282
+ it 'should sell at the net price' do
283
+ expect(line_item.price).to eq(18.69)
284
+ end
285
+
286
+ it 'is adjusted to the net price' do
287
+ expect(line_item.total).to eq(18.69)
288
+ end
289
+
290
+ it 'has no tax adjustments' do
291
+ expect(line_item.adjustments.tax.count).to eq(0)
292
+ end
293
+
294
+ it 'has no included tax' do
295
+ expect(line_item.included_tax_total).to eq(0)
296
+ end
297
+
298
+ it 'has no additional tax' do
299
+ expect(line_item.additional_tax_total).to eq(0)
300
+ end
301
+
302
+ it 'has a constant amount pre tax' do
303
+ expect(line_item.discounted_amount - line_item.included_tax_total).to eq(18.69)
304
+ end
305
+ end
306
+
307
+ context 'an order with a sweater' do
308
+ let(:variant) { sweater }
309
+
310
+ it 'should sell at the net price' do
311
+ expect(line_item.price).to eq(25.21)
312
+ end
313
+
314
+ it 'has no tax adjustments' do
315
+ expect(line_item.adjustments.tax.count).to eq(0)
316
+ end
317
+
318
+ it 'has no included tax' do
319
+ expect(line_item.included_tax_total).to eq(0)
320
+ end
321
+
322
+ it 'has no additional tax' do
323
+ expect(line_item.additional_tax_total).to eq(0)
324
+ end
325
+
326
+ it 'has a constant amount pre tax' do
327
+ expect(line_item.discounted_amount - line_item.included_tax_total).to eq(25.21)
328
+ end
329
+ end
330
+
331
+ context 'an order with a download' do
332
+ let(:variant) { download }
333
+
334
+ it 'should sell at the net price' do
335
+ expect(line_item.price).to eq(8.40)
336
+ end
337
+
338
+ it 'has no tax adjustments' do
339
+ expect(line_item.adjustments.tax.count).to eq(0)
340
+ end
341
+
342
+ it 'has no included tax' do
343
+ expect(line_item.included_tax_total).to eq(0)
344
+ end
345
+
346
+ it 'has no additional tax' do
347
+ expect(line_item.additional_tax_total).to eq(0)
348
+ end
349
+
350
+ it 'has a constant amount pre tax' do
351
+ expect(line_item.discounted_amount - line_item.included_tax_total).to eq(8.40)
352
+ end
353
+ end
354
+ end
355
+ end
356
+ end
@@ -17,6 +17,7 @@ RSpec.describe 'state factory' do
17
17
 
18
18
  describe 'when given a country iso code' do
19
19
  let(:state) { build(:state, country_iso: "DE") }
20
+
20
21
  it 'creates the first state for that country it finds in carmen' do
21
22
  expect(state.abbr).to eq("BW")
22
23
  expect(state.name).to eq("Baden-Württemberg")
@@ -45,4 +46,12 @@ RSpec.describe 'state factory' do
45
46
  expect{ build(:state, country_iso: "ZZ") }.to raise_error(RuntimeError, 'Unknown country iso code: "ZZ"')
46
47
  end
47
48
  end
49
+
50
+ context 'with a country that does not have subregions' do
51
+ it 'raises an exception' do
52
+ expect {
53
+ create(:state, country_iso: 'HK')
54
+ }.to raise_error('Country HK has no subregions')
55
+ end
56
+ end
48
57
  end
@@ -21,4 +21,13 @@ RSpec.describe 'stock location factory' do
21
21
 
22
22
  it_behaves_like 'a working factory'
23
23
  end
24
+
25
+ describe 'stock location for a country without subregions' do
26
+ let(:country) { create(:country, iso: 'HK') }
27
+ it 'succeeds' do
28
+ expect(
29
+ create(:stock_location, country: country)
30
+ ).to be_a(Spree::StockLocation)
31
+ end
32
+ end
24
33
  end
@@ -8,6 +8,81 @@ describe Spree::Money do
8
8
  end
9
9
  end
10
10
 
11
+ describe '#initialize' do
12
+ subject do
13
+ Spree::Deprecation.silence do
14
+ described_class.new(amount, currency: currency, with_currency: true).to_s
15
+ end
16
+ end
17
+
18
+ context 'with no currency' do
19
+ let(:currency) { nil }
20
+ let(:amount){ 10 }
21
+ it { should == "$10.00 USD" }
22
+ end
23
+
24
+ context 'with currency' do
25
+ let(:currency){ 'USD' }
26
+
27
+ context "CAD" do
28
+ let(:amount){ '10.00' }
29
+ let(:currency){ 'CAD' }
30
+ it { should == "$10.00 CAD" }
31
+ end
32
+
33
+ context "with string amount" do
34
+ let(:amount){ '10.00' }
35
+ it { should == "$10.00 USD" }
36
+ end
37
+
38
+ context "with no decimal point" do
39
+ let(:amount){ '10' }
40
+ it { should == "$10.00 USD" }
41
+ end
42
+
43
+ context "with symbol" do
44
+ let(:amount){ '$10.00' }
45
+ it { should == "$10.00 USD" }
46
+ end
47
+
48
+ context "with extra currency" do
49
+ let(:amount){ '$10.00 USD' }
50
+ it { should == "$10.00 USD" }
51
+ end
52
+
53
+ context "with different currency" do
54
+ let(:currency){ 'USD' }
55
+ let(:amount){ '$10.00 CAD' }
56
+ it { should == "$10.00 CAD" }
57
+ end
58
+
59
+ context "with commas" do
60
+ let(:amount){ '1,000.00' }
61
+ it { should == "$1,000.00 USD" }
62
+ end
63
+
64
+ context "with comma for decimal point" do
65
+ let(:amount){ '10,00' }
66
+ it { should == "$10.00 USD" }
67
+ end
68
+
69
+ context 'with fixnum' do
70
+ let(:amount){ 10 }
71
+ it { should == "$10.00 USD" }
72
+ end
73
+
74
+ context 'with float' do
75
+ let(:amount){ 10.00 }
76
+ it { should == "$10.00 USD" }
77
+ end
78
+
79
+ context 'with BigDecimal' do
80
+ let(:amount){ BigDecimal.new('10.00') }
81
+ it { should == "$10.00 USD" }
82
+ end
83
+ end
84
+ end
85
+
11
86
  it "formats correctly" do
12
87
  money = Spree::Money.new(10)
13
88
  expect(money.to_s).to eq("$10.00")
@@ -20,16 +20,16 @@ describe Spree::AppConfiguration, type: :model do
20
20
  expect(prefs.variant_search_class).to eq Spree::Core::Search::Variant
21
21
  end
22
22
 
23
- it "uses variant pricer class by default" do
24
- expect(prefs.variant_pricer_class).to eq Spree::Variant::Pricer
23
+ it "uses variant price selector class by default" do
24
+ expect(prefs.variant_price_selector_class).to eq Spree::Variant::PriceSelector
25
25
  end
26
26
 
27
- it "has a getter for the pricing options class provided by the variant pricer class" do
28
- expect(prefs.pricing_options_class).to eq Spree::Variant::Pricer.pricing_options_class
27
+ it "has a getter for the pricing options class provided by the variant price selector class" do
28
+ expect(prefs.pricing_options_class).to eq Spree::Variant::PriceSelector.pricing_options_class
29
29
  end
30
30
 
31
31
  it "has an instacached getter for the default pricing options" do
32
- expect(prefs.default_pricing_options).to be_a Spree::Variant::Pricer.pricing_options_class
32
+ expect(prefs.default_pricing_options).to be_a Spree::Variant::PriceSelector.pricing_options_class
33
33
  expect(prefs.default_pricing_options.object_id).to eq prefs.default_pricing_options.object_id
34
34
  end
35
35