solidus_volume_pricing 0.1.0

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.
Files changed (67) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/.hound.yml +40 -0
  4. data/.rspec +3 -0
  5. data/.rubocop.yml +8 -0
  6. data/.travis.yml +14 -0
  7. data/CONTRIBUTING.md +81 -0
  8. data/Gemfile +13 -0
  9. data/Guardfile +9 -0
  10. data/LICENSE.md +26 -0
  11. data/README.md +112 -0
  12. data/Rakefile +21 -0
  13. data/app/assets/javascripts/spree/backend/solidus_volume_pricing.js +16 -0
  14. data/app/controllers/spree/admin/variants_controller_decorator.rb +32 -0
  15. data/app/controllers/spree/admin/volume_price_models_controller.rb +27 -0
  16. data/app/controllers/spree/admin/volume_prices_controller.rb +11 -0
  17. data/app/helpers/spree/base_helper_decorator.rb +19 -0
  18. data/app/models/spree/line_item_decorator.rb +27 -0
  19. data/app/models/spree/user_decorator.rb +10 -0
  20. data/app/models/spree/variant_decorator.rb +104 -0
  21. data/app/models/spree/volume_price.rb +35 -0
  22. data/app/models/spree/volume_price_model.rb +8 -0
  23. data/app/overrides/spree/admin/shared/sub_menu/_configuration/add_volume_price_model_admin_menu_links.html.erb.deface +3 -0
  24. data/app/overrides/views_decorator.rb +13 -0
  25. data/app/views/spree/admin/shared/_vp_product_tab.html.erb +3 -0
  26. data/app/views/spree/admin/variants/_edit_fields.html.erb +33 -0
  27. data/app/views/spree/admin/variants/volume_prices.html.erb +39 -0
  28. data/app/views/spree/admin/volume_price_models/_form.html.erb +9 -0
  29. data/app/views/spree/admin/volume_price_models/_list.html.erb +23 -0
  30. data/app/views/spree/admin/volume_price_models/edit.html.erb +12 -0
  31. data/app/views/spree/admin/volume_price_models/index.html.erb +18 -0
  32. data/app/views/spree/admin/volume_price_models/new.html.erb +12 -0
  33. data/app/views/spree/admin/volume_prices/_edit_fields.html.erb +31 -0
  34. data/app/views/spree/admin/volume_prices/_volume_price_fields.html.erb +33 -0
  35. data/app/views/spree/products/_volume_pricing.html.erb +15 -0
  36. data/bin/rails +7 -0
  37. data/config/locales/de.yml +18 -0
  38. data/config/locales/en.yml +18 -0
  39. data/config/locales/pt.yml +18 -0
  40. data/config/locales/ru.yml +18 -0
  41. data/config/locales/sv.yml +18 -0
  42. data/config/locales/tr.yml +18 -0
  43. data/config/routes.rb +12 -0
  44. data/db/migrate/20081119145604_create_volume_prices.rb +16 -0
  45. data/db/migrate/20110203174010_change_display_name_for_volume_prices.rb +9 -0
  46. data/db/migrate/20111206173307_prefix_volume_pricing_table_names.rb +5 -0
  47. data/db/migrate/20121115043422_add_discount_type_column.rb +5 -0
  48. data/db/migrate/20150513200904_add_role_to_volume_price.rb +5 -0
  49. data/db/migrate/20150603143015_create_spree_volume_price_models.rb +18 -0
  50. data/lib/generators/solidus_volume_pricing/install/install_generator.rb +24 -0
  51. data/lib/solidus_volume_pricing.rb +6 -0
  52. data/lib/solidus_volume_pricing/engine.rb +42 -0
  53. data/lib/solidus_volume_pricing/version.rb +18 -0
  54. data/solidus_volume_pricing.gemspec +40 -0
  55. data/spec/controllers/spree/admin/variants_controller_spec.rb +27 -0
  56. data/spec/factories/volume_price_factory.rb +12 -0
  57. data/spec/helpers/base_helper_spec.rb +22 -0
  58. data/spec/models/spree/line_item_spec.rb +34 -0
  59. data/spec/models/spree/order_spec.rb +49 -0
  60. data/spec/models/spree/variant_spec.rb +306 -0
  61. data/spec/models/spree/volume_price_spec.rb +121 -0
  62. data/spec/spec_helper.rb +41 -0
  63. data/spec/support/capybara.rb +12 -0
  64. data/spec/support/database_cleaner.rb +24 -0
  65. data/spec/support/factory_girl.rb +7 -0
  66. data/spec/support/spree.rb +10 -0
  67. metadata +337 -0
@@ -0,0 +1,49 @@
1
+ RSpec.describe Spree::Order, type: :model do
2
+ before do
3
+ @order = create(:order)
4
+ @variant = create(:variant, price: 10)
5
+
6
+ @variant_with_prices = create(:variant, price: 10)
7
+ @variant_with_prices.volume_prices << create(:volume_price, range: '1..5', amount: 9, position: 2)
8
+ @variant_with_prices.volume_prices << create(:volume_price, range: '(5..9)', amount: 8, position: 1)
9
+ end
10
+
11
+ context 'add_variant' do
12
+ it 'uses the variant price if there are no volume prices' do
13
+ @order.contents.add(@variant)
14
+ expect(@order.line_items.first.price).to eq(10)
15
+ end
16
+
17
+ it 'uses the volume price if quantity falls within a quantity range of a volume price' do
18
+ @variant.volume_prices << create(:volume_price, range: '(5..10)', amount: 9)
19
+ @order.contents.add(@variant_with_prices, 7)
20
+ expect(@order.line_items.first.price).to eq(8)
21
+ end
22
+
23
+ it 'uses the variant price if the quantity fails to satisfy any of the volume price ranges' do
24
+ @order.contents.add(@variant, 10)
25
+ expect(@order.line_items.first.price).to eq(10)
26
+ end
27
+
28
+ it 'uses the first matching volume price in the event of more then one matching volume prices' do
29
+ @order.contents.add(@variant_with_prices, 5)
30
+ expect(@order.line_items.first.price).to eq(8)
31
+ end
32
+
33
+ it 'uses the master variant volume price in case variant has no volume price if config is true' do
34
+ Spree::Config.use_master_variant_volume_pricing = true
35
+ @master = @variant.product.master
36
+ @master.volume_prices << create(:volume_price, range: '(1..5)', amount: 9, position: 2)
37
+ @order.contents.add(@variant, 5)
38
+ expect(@order.line_items.first.price).to eq(9)
39
+ end
40
+
41
+ it 'doesnt use the master variant volume price in case variant has no volume price if config is false' do
42
+ Spree::Config.use_master_variant_volume_pricing = false
43
+ @master = @variant.product.master
44
+ @master.volume_prices << create(:volume_price, range: '(1..5)', amount: 9, position: 2)
45
+ @order.contents.add(@variant, 5)
46
+ expect(@order.line_items.first.price).to eq(10)
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,306 @@
1
+ RSpec.describe Spree::Variant, type: :model do
2
+ it { is_expected.to have_many(:volume_prices) }
3
+
4
+ describe '#volume_price' do
5
+
6
+ context 'discount_type = price' do
7
+ before :each do
8
+ @variant = create :variant, price: 10
9
+ @variant.volume_prices.create! amount: 9, discount_type: 'price', range: '(10+)'
10
+ @role = create(:role)
11
+ @user = create(:user)
12
+ end
13
+
14
+ it 'uses the variants price when it does not match a range' do
15
+ expect(@variant.volume_price(1).to_f).to be(10.00)
16
+ end
17
+
18
+ it 'uses the variants price when it does not match role with null role' do
19
+ @variant.volume_prices.first.update(role_id: @role.id)
20
+ expect(@variant.volume_price(10).to_f).to be(10.00)
21
+ end
22
+
23
+ it 'uses the variants price when it does not match roles' do
24
+ other_role = create(:role)
25
+ @user.spree_roles << other_role
26
+ @variant.volume_prices.first.update(role_id: @role.id)
27
+ expect(@variant.volume_price(10, @user).to_f).to be(10.00)
28
+ end
29
+
30
+ it 'uses the volume price when it does match a range' do
31
+ expect(@variant.volume_price(10).to_f).to be(9.00)
32
+ end
33
+
34
+ it 'uses the volume price when it does match a range and role' do
35
+ @user.spree_roles << @role
36
+ Spree::Config.volume_pricing_role = @role.name
37
+ @variant.volume_prices.first.update(role_id: @role.id)
38
+ expect(@variant.volume_price(10, @user).to_f).to be(9.00)
39
+ end
40
+
41
+ it 'uses the volume price when it does match from a volume price model' do
42
+ @variant.volume_price_models << create(:volume_price_model)
43
+ @variant.volume_price_models.first.volume_prices.create!(amount: 5, discount_type: 'price', range: '(5+)')
44
+ expect(@variant.volume_price(6).to_f).to be(5.00)
45
+ end
46
+
47
+ it 'gives percent of earning without role' do
48
+ expect(@variant.volume_price_earning_percent(10)).to be(10)
49
+ end
50
+
51
+ it 'gives percent of earning if role matches' do
52
+ @user.spree_roles << @role
53
+ Spree::Config.volume_pricing_role = @role.name
54
+ @variant.volume_prices.first.update(role_id: @role.id)
55
+ expect(@variant.volume_price_earning_percent(10, @user)).to be(10)
56
+ end
57
+
58
+ it 'gives zero percent earning if doesnt match' do
59
+ expect(@variant.volume_price_earning_percent(1)).to be(0)
60
+ end
61
+
62
+ it 'gives zero percent earning if role doesnt match with null' do
63
+ @variant.volume_prices.first.update(role_id: @role.id)
64
+ expect(@variant.volume_price_earning_percent(10)).to be(0)
65
+ end
66
+
67
+ it 'gives zero percent earning if role doesnt match' do
68
+ other_role = create(:role)
69
+ @user.spree_roles << other_role
70
+ @variant.volume_prices.first.update(role_id: @role.id)
71
+ expect(@variant.volume_price_earning_percent(10, @user)).to be(0)
72
+ end
73
+
74
+ it 'gives amount earning without role' do
75
+ expect(@variant.volume_price_earning_amount(10)).to eq(1)
76
+ end
77
+
78
+ it 'gives amount earning if role matches' do
79
+ @user.spree_roles << @role
80
+ Spree::Config.volume_pricing_role = @role.name
81
+ @variant.volume_prices.first.update(role_id: @role.id)
82
+ expect(@variant.volume_price_earning_amount(10, @user)).to eq(1)
83
+ end
84
+
85
+ it 'gives zero earning amount if doesnt match' do
86
+ expect(@variant.volume_price_earning_amount(1)).to eq(0)
87
+ end
88
+
89
+ it 'gives zero earning amount if role doesnt match with null' do
90
+ @variant.volume_prices.first.update(role_id: @role.id)
91
+ expect(@variant.volume_price_earning_amount(10)).to be(0)
92
+ end
93
+
94
+ it 'gives zero earning amount if role doesnt match' do
95
+ other_role = create(:role)
96
+ @user.spree_roles << other_role
97
+ @variant.volume_prices.first.update(role_id: @role.id)
98
+ expect(@variant.volume_price_earning_amount(10, @user)).to be(0)
99
+ end
100
+ end
101
+
102
+ context 'discount_type = dollar' do
103
+ before :each do
104
+ @variant = create :variant, price: 10
105
+ @variant.volume_prices.create! amount: 1, discount_type: 'dollar', range: '(10+)'
106
+ @role = create(:role)
107
+ @user = create(:user)
108
+ end
109
+
110
+ it 'uses the variants price when it does not match a range' do
111
+ expect(@variant.volume_price(1).to_f).to be(10.00)
112
+ end
113
+
114
+ it 'uses the variants price when it does not match role with null role' do
115
+ @variant.volume_prices.first.update(role_id: @role.id)
116
+ expect(@variant.volume_price(10).to_f).to be(10.00)
117
+ end
118
+
119
+ it 'uses the variants price when it does not match roles' do
120
+ other_role = create(:role)
121
+ @user.spree_roles << other_role
122
+ @variant.volume_prices.first.update(role_id: @role.id)
123
+ expect(@variant.volume_price(10, @user).to_f).to be(10.00)
124
+ end
125
+
126
+ it 'uses the volume price when it does match a range' do
127
+ expect(@variant.volume_price(10).to_f).to be(9.00)
128
+ end
129
+
130
+ it 'uses the volume price when it does match a range and role' do
131
+ @user.spree_roles << @role
132
+ Spree::Config.volume_pricing_role = @role.name
133
+ @variant.volume_prices.first.update(role_id: @role.id)
134
+ expect(@variant.volume_price(10, @user).to_f).to be(9.00)
135
+ end
136
+
137
+ it 'uses the volume price when it does match from a volume price model' do
138
+ @variant.volume_price_models << create(:volume_price_model)
139
+ @variant.volume_price_models.first.volume_prices.create!(amount: 5, discount_type: 'dollar', range: '(5+)')
140
+ expect(@variant.volume_price(6).to_f).to be(5.00)
141
+ end
142
+
143
+ it 'gives percent of earning without role' do
144
+ expect(@variant.volume_price_earning_percent(10)).to be(10)
145
+ end
146
+
147
+ it 'gives percent of earning if role matches' do
148
+ @user.spree_roles << @role
149
+ Spree::Config.volume_pricing_role = @role.name
150
+ @variant.volume_prices.first.update(role_id: @role.id)
151
+ expect(@variant.volume_price_earning_percent(10, @user)).to be(10)
152
+ end
153
+
154
+ it 'gives zero percent earning if doesnt match' do
155
+ expect(@variant.volume_price_earning_percent(1)).to be(0)
156
+ end
157
+
158
+ it 'gives zero percent earning if role doesnt match with null' do
159
+ @variant.volume_prices.first.update(role_id: @role.id)
160
+ expect(@variant.volume_price_earning_percent(10)).to be(0)
161
+ end
162
+
163
+ it 'gives zero percent earning if role doesnt match' do
164
+ other_role = create(:role)
165
+ @user.spree_roles << other_role
166
+ @variant.volume_prices.first.update(role_id: @role.id)
167
+ expect(@variant.volume_price_earning_percent(10, @user)).to be(0)
168
+ end
169
+
170
+ it 'gives amount earning without role' do
171
+ expect(@variant.volume_price_earning_amount(10)).to eq(1)
172
+ end
173
+
174
+ it 'gives amount earning if role matches' do
175
+ @user.spree_roles << @role
176
+ Spree::Config.volume_pricing_role = @role.name
177
+ @variant.volume_prices.first.update(role_id: @role.id)
178
+ expect(@variant.volume_price_earning_amount(10, @user)).to eq(1)
179
+ end
180
+
181
+ it 'gives zero earning amount if doesnt match' do
182
+ expect(@variant.volume_price_earning_amount(1)).to eq(0)
183
+ end
184
+
185
+ it 'gives zero earning amount if role doesnt match with null' do
186
+ @variant.volume_prices.first.update(role_id: @role.id)
187
+ expect(@variant.volume_price_earning_amount(10)).to be(0)
188
+ end
189
+
190
+ it 'gives zero earning amount if role doesnt match' do
191
+ other_role = create(:role)
192
+ @user.spree_roles << other_role
193
+ @variant.volume_prices.first.update(role_id: @role.id)
194
+ expect(@variant.volume_price_earning_amount(10, @user)).to be(0)
195
+ end
196
+ end
197
+
198
+ context 'discount_type = percent' do
199
+ before :each do
200
+ @variant = create :variant, price: 10
201
+ @variant.volume_prices.create! amount: 0.1, discount_type: 'percent', range: '(10+)'
202
+ @role = create(:role)
203
+ @user = create(:user)
204
+ end
205
+
206
+ it 'uses the variants price when it does not match a range' do
207
+ expect(@variant.volume_price(1).to_f).to be(10.00)
208
+ end
209
+
210
+ it 'uses the variants price when it does not match role with null role' do
211
+ @variant.volume_prices.first.update(role_id: @role.id)
212
+ expect(@variant.volume_price(10).to_f).to be(10.00)
213
+ end
214
+
215
+ it 'uses the variants price when it does not match roles' do
216
+ other_role = create(:role)
217
+ @user.spree_roles << other_role
218
+ @variant.volume_prices.first.update(role_id: @role.id)
219
+ expect(@variant.volume_price(10, @user).to_f).to be(10.00)
220
+ end
221
+
222
+ it 'uses the volume price when it does match a range' do
223
+ expect(@variant.volume_price(10).to_f).to be(9.00)
224
+ end
225
+
226
+ it 'uses the volume price when it does match a range and role' do
227
+ @user.spree_roles << @role
228
+ Spree::Config.volume_pricing_role = @role.name
229
+ @variant.volume_prices.first.update(role_id: @role.id)
230
+ expect(@variant.volume_price(10, @user).to_f).to be(9.00)
231
+ end
232
+
233
+ it 'gives percent of earning without roles' do
234
+ expect(@variant.volume_price_earning_percent(10)).to be(10)
235
+ @variant_five = create :variant, price: 10
236
+ @variant_five.volume_prices.create! amount: 0.5, discount_type: 'percent', range: '(1+)'
237
+ expect(@variant_five.volume_price_earning_percent(1)).to be(50)
238
+ end
239
+
240
+ it 'gives amount earning if role matches' do
241
+ @user.spree_roles << @role
242
+ Spree::Config.volume_pricing_role = @role.name
243
+ expect(@variant.volume_price_earning_percent(10)).to be(10)
244
+ @variant_five = create :variant, price: 10
245
+ @variant_five.volume_prices.create! amount: 0.5, discount_type: 'percent', range: '(1+)'
246
+ @variant_five.volume_prices.first.update(role_id: @role.id)
247
+ expect(@variant_five.volume_price_earning_percent(1, @user)).to be(50)
248
+ end
249
+
250
+ it 'gives zero percent earning if doesnt match' do
251
+ expect(@variant.volume_price_earning_percent(1)).to be(0)
252
+ end
253
+
254
+ it 'gives zero percent earning if role doesnt match with null' do
255
+ @variant.volume_prices.first.update(role_id: @role.id)
256
+ expect(@variant.volume_price_earning_percent(10)).to be(0)
257
+ end
258
+
259
+ it 'gives zero percent earning if role doesnt match' do
260
+ other_role = create(:role)
261
+ @user.spree_roles << other_role
262
+ @variant.volume_prices.first.update(role_id: @role.id)
263
+ expect(@variant.volume_price_earning_percent(10, @user)).to be(0)
264
+ end
265
+
266
+ it 'gives amount earning without roles' do
267
+ expect(@variant.volume_price_earning_amount(10)).to eq(1)
268
+ @variant_five = create :variant, price: 10
269
+ @variant_five.volume_prices.create! amount: 0.5, discount_type: 'percent', range: '(1+)'
270
+ expect(@variant_five.volume_price_earning_amount(1)).to eq(5)
271
+ end
272
+
273
+ it 'gives amount earning if role matches' do
274
+ @user.spree_roles << @role
275
+ Spree::Config.volume_pricing_role = @role.name
276
+ expect(@variant.volume_price_earning_amount(10)).to eq(1)
277
+ @variant_five = create :variant, price: 10
278
+ @variant_five.volume_prices.create! amount: 0.5, discount_type: 'percent', range: '(1+)'
279
+ @variant_five.volume_prices.first.update(role_id: @role.id)
280
+ expect(@variant_five.volume_price_earning_amount(1, @user)).to eq(5)
281
+ end
282
+
283
+ it 'uses the volume price when it does match from a volume price model' do
284
+ @variant.volume_price_models << create(:volume_price_model)
285
+ @variant.volume_price_models.first.volume_prices.create!(amount: 0.5, discount_type: 'percent', range: '(5+)')
286
+ expect(@variant.volume_price(6).to_f).to be(5.00)
287
+ end
288
+
289
+ it 'gives zero earning amount if doesnt match' do
290
+ expect(@variant.volume_price_earning_amount(1)).to eq(0)
291
+ end
292
+
293
+ it 'gives zero earning amount if role doesnt match with null' do
294
+ @variant.volume_prices.first.update(role_id: @role.id)
295
+ expect(@variant.volume_price_earning_amount(10)).to be(0)
296
+ end
297
+
298
+ it 'gives zero earning amount if role doesnt match' do
299
+ other_role = create(:role)
300
+ @user.spree_roles << other_role
301
+ @variant.volume_prices.first.update(role_id: @role.id)
302
+ expect(@variant.volume_price_earning_amount(10, @user)).to be(0)
303
+ end
304
+ end
305
+ end
306
+ end
@@ -0,0 +1,121 @@
1
+ RSpec.describe Spree::VolumePrice, type: :model do
2
+ it { is_expected.to belong_to(:variant).touch(true) }
3
+ it { is_expected.to belong_to(:volume_price_model).touch(true) }
4
+ it { is_expected.to belong_to(:spree_role).class_name('Spree::Role').with_foreign_key('role_id') }
5
+ it { is_expected.to validate_presence_of(:discount_type) }
6
+ it { is_expected.to validate_inclusion_of(:discount_type).in_array(%w(price dollar percent)) }
7
+ it { is_expected.to validate_presence_of(:amount) }
8
+
9
+ before do
10
+ @volume_price = Spree::VolumePrice.new(variant: Spree::Variant.new, amount: 10, discount_type: 'price')
11
+ end
12
+
13
+ ['1..2', '(1..2)'].each do |range|
14
+ it "does not interepret a Ruby range of #{range} as being opend ended" do
15
+ @volume_price.range = range
16
+ expect(@volume_price).not_to be_open_ended
17
+ end
18
+ end
19
+
20
+ ['50+', '(50+)'].each do |range|
21
+ it "properly interpret an open ended range of #{range}" do
22
+ @volume_price.range = range
23
+ expect(@volume_price).to be_open_ended
24
+ end
25
+ end
26
+
27
+ describe 'valid range format' do
28
+ it 'requires the presence of a variant' do
29
+ @volume_price.variant = nil
30
+ expect(@volume_price).not_to be_valid
31
+ end
32
+
33
+ it 'consider a range of (1..2) to be valid' do
34
+ @volume_price.range = '(1..2)'
35
+ expect(@volume_price).to be_valid
36
+ end
37
+
38
+ it 'consider a range of (1...2) to be valid' do
39
+ @volume_price.range = '(1...2)'
40
+ expect(@volume_price).to be_valid
41
+ end
42
+
43
+ it 'consider a range of 1..2 to be valid' do
44
+ @volume_price.range = '1..2'
45
+ expect(@volume_price).to be_valid
46
+ end
47
+
48
+ it 'consider a range of 1...2 to be valid' do
49
+ @volume_price.range = '1...2'
50
+ expect(@volume_price).to be_valid
51
+ end
52
+
53
+ it 'consider a range of (10+) to be valid' do
54
+ @volume_price.range = '(10+)'
55
+ expect(@volume_price).to be_valid
56
+ end
57
+
58
+ it 'consider a range of 10+ to be valid' do
59
+ @volume_price.range = '10+'
60
+ expect(@volume_price).to be_valid
61
+ end
62
+
63
+ it 'does not consider a range of 1-2 to valid' do
64
+ @volume_price.range = '1-2'
65
+ expect(@volume_price).not_to be_valid
66
+ end
67
+
68
+ it 'does not consider a range of 1 to valid' do
69
+ @volume_price.range = '1'
70
+ expect(@volume_price).not_to be_valid
71
+ end
72
+
73
+ it 'does not consider a range of foo to valid' do
74
+ @volume_price.range = 'foo'
75
+ expect(@volume_price).not_to be_valid
76
+ end
77
+ end
78
+
79
+ describe 'include?' do
80
+ ['10..20', '(10..20)'].each do |range|
81
+ it "does not match a quantity that fails to fall within the specified range of #{range}" do
82
+ @volume_price.range = range
83
+ expect(@volume_price).not_to include(21)
84
+ end
85
+
86
+ it "matches a quantity that is within the specified range of #{range}" do
87
+ @volume_price.range = range
88
+ expect(@volume_price).to include(12)
89
+ end
90
+
91
+ it 'matches the upper bound of ranges that include the upper bound' do
92
+ @volume_price.range = range
93
+ expect(@volume_price).to include(20)
94
+ end
95
+ end
96
+
97
+ ['10...20', '(10...20)'].each do |range|
98
+ it 'does not match the upper bound for ranges that exclude the upper bound' do
99
+ @volume_price.range = range
100
+ expect(@volume_price).not_to include(20)
101
+ end
102
+ end
103
+
104
+ ['50+', '(50+)'].each do |range|
105
+ it "matches a quantity that exceeds the value of an open ended range of #{range}" do
106
+ @volume_price.range = range
107
+ expect(@volume_price).to include(51)
108
+ end
109
+
110
+ it "matches a quantity that equals the value of an open ended range of #{range}" do
111
+ @volume_price.range = range
112
+ expect(@volume_price).to include(50)
113
+ end
114
+
115
+ it "does not match a quantity that is less then the value of an open ended range of #{range}" do
116
+ @volume_price.range = range
117
+ expect(@volume_price).not_to include(40)
118
+ end
119
+ end
120
+ end
121
+ end