solidus_volume_pricing 0.2.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. checksums.yaml +5 -5
  2. data/.circleci/config.yml +35 -0
  3. data/.gem_release.yml +5 -0
  4. data/.github/dependabot.yml +7 -0
  5. data/.github/stale.yml +17 -0
  6. data/.gitignore +14 -9
  7. data/.rspec +2 -2
  8. data/.rubocop.yml +3 -7
  9. data/.rubocop_todo.yml +126 -0
  10. data/CHANGELOG.md +86 -0
  11. data/Gemfile +25 -2
  12. data/Guardfile +3 -1
  13. data/{LICENSE.md → LICENSE} +2 -2
  14. data/README.md +55 -50
  15. data/Rakefile +4 -19
  16. data/app/assets/javascripts/spree/backend/solidus_volume_pricing.js +1 -15
  17. data/app/controllers/spree/admin/volume_price_models_controller.rb +2 -1
  18. data/app/controllers/spree/admin/volume_prices_controller.rb +3 -1
  19. data/app/decorators/controllers/solidus_volume_pricing/spree/admin/variants_controller_decorator.rb +42 -0
  20. data/app/decorators/helpers/solidus_volume_pricing/spree/base_helper_decorator.rb +31 -0
  21. data/app/decorators/models/solidus_volume_pricing/spree/line_item_decorator.rb +18 -0
  22. data/app/decorators/models/solidus_volume_pricing/spree/variant_decorator.rb +21 -0
  23. data/app/models/solidus_volume_pricing/price_display.rb +47 -0
  24. data/app/models/solidus_volume_pricing/pricer.rb +95 -0
  25. data/app/models/solidus_volume_pricing/pricing_options.rb +20 -0
  26. data/app/models/spree/volume_price.rb +43 -26
  27. data/app/models/spree/volume_price_model.rb +6 -4
  28. data/app/overrides/spree/admin/shared/_settings_sub_menu/add_volume_price_model_admin_menu_links.html.erb.deface +5 -0
  29. data/app/overrides/views_decorator.rb +2 -0
  30. data/app/views/spree/admin/shared/_vp_product_tab.html.erb +2 -2
  31. data/app/views/spree/admin/variants/_edit_fields.html.erb +5 -32
  32. data/app/views/spree/admin/variants/volume_prices.html.erb +9 -36
  33. data/app/views/spree/admin/volume_price_models/_form.html.erb +6 -2
  34. data/app/views/spree/admin/volume_price_models/_list.html.erb +8 -4
  35. data/app/views/spree/admin/volume_price_models/_select.html.erb +17 -0
  36. data/app/views/spree/admin/volume_price_models/edit.html.erb +7 -6
  37. data/app/views/spree/admin/volume_price_models/index.html.erb +7 -5
  38. data/app/views/spree/admin/volume_price_models/new.html.erb +5 -5
  39. data/app/views/spree/admin/volume_prices/_table.html.erb +26 -0
  40. data/app/views/spree/admin/volume_prices/_volume_price_fields.html.erb +10 -8
  41. data/app/views/spree/products/_volume_pricing.html.erb +8 -8
  42. data/bin/console +17 -0
  43. data/bin/rails +12 -4
  44. data/bin/setup +8 -0
  45. data/config/locales/de.yml +17 -3
  46. data/config/locales/en.yml +21 -2
  47. data/config/locales/pt.yml +6 -2
  48. data/config/locales/ru.yml +6 -2
  49. data/config/locales/sv.yml +6 -2
  50. data/config/locales/tr.yml +6 -2
  51. data/config/routes.rb +3 -1
  52. data/db/migrate/20081119145604_create_volume_prices.rb +3 -1
  53. data/db/migrate/20110203174010_change_display_name_for_volume_prices.rb +3 -1
  54. data/db/migrate/20111206173307_prefix_volume_pricing_table_names.rb +3 -1
  55. data/db/migrate/20121115043422_add_discount_type_column.rb +3 -1
  56. data/db/migrate/20150513200904_add_role_to_volume_price.rb +3 -1
  57. data/db/migrate/20150603143015_create_spree_volume_price_models.rb +3 -1
  58. data/lib/generators/solidus_volume_pricing/install/install_generator.rb +5 -5
  59. data/lib/solidus_volume_pricing/engine.rb +16 -24
  60. data/lib/solidus_volume_pricing/range_from_string.rb +36 -0
  61. data/lib/solidus_volume_pricing/testing_support/factories.rb +14 -0
  62. data/lib/solidus_volume_pricing/version.rb +3 -16
  63. data/lib/solidus_volume_pricing.rb +6 -1
  64. data/solidus_volume_pricing.gemspec +26 -23
  65. data/spec/controllers/spree/admin/variants_controller_spec.rb +18 -15
  66. data/spec/features/manage_volume_price_models_feature_spec.rb +5 -7
  67. data/spec/features/manage_volume_prices_feature_spec.rb +9 -8
  68. data/spec/helpers/base_helper_spec.rb +3 -1
  69. data/spec/lib/solidus_volume_pricing/range_from_string_spec.rb +61 -0
  70. data/spec/models/solidus_volume_pricing/pricer_spec.rb +669 -0
  71. data/spec/models/solidus_volume_pricing/pricing_options_spec.rb +57 -0
  72. data/spec/models/spree/line_item_spec.rb +23 -21
  73. data/spec/models/spree/order_spec.rb +4 -2
  74. data/spec/models/spree/variant_spec.rb +3 -303
  75. data/spec/models/spree/volume_price_spec.rb +145 -50
  76. data/spec/spec_helper.rb +15 -35
  77. data/spec/support/shoulda.rb +11 -0
  78. metadata +83 -161
  79. data/.hound.yml +0 -40
  80. data/.travis.yml +0 -12
  81. data/CONTRIBUTING.md +0 -81
  82. data/app/controllers/spree/admin/variants_controller_decorator.rb +0 -32
  83. data/app/helpers/spree/base_helper_decorator.rb +0 -19
  84. data/app/models/spree/line_item_decorator.rb +0 -13
  85. data/app/models/spree/user_decorator.rb +0 -10
  86. data/app/models/spree/variant_decorator.rb +0 -104
  87. data/app/overrides/spree/admin/shared/sub_menu/_configuration/add_volume_price_model_admin_menu_links.html.erb.deface +0 -3
  88. data/app/views/spree/admin/volume_prices/_edit_fields.html.erb +0 -31
  89. data/spec/factories/volume_price_factory.rb +0 -12
  90. data/spec/support/capybara.rb +0 -12
  91. data/spec/support/database_cleaner.rb +0 -21
  92. data/spec/support/factory_girl.rb +0 -7
  93. data/spec/support/spree.rb +0 -10
@@ -1,34 +1,36 @@
1
+ # frozen_string_literal: true
2
+
1
3
  RSpec.describe Spree::LineItem, type: :model do
4
+ let(:order) { create(:order) }
5
+ let(:variant) { create(:variant, price: 10) }
6
+ let(:line_item) { order.line_items.first }
7
+ let(:role) { create(:role) }
8
+
2
9
  before do
3
- @order = create(:order)
4
- @variant = create(:variant, price: 10)
5
- @variant.volume_prices.create! amount: 9, discount_type: 'price', range: '(2+)'
6
- @order.contents.add(@variant, 1)
7
- @line_item = @order.line_items.first
8
- @role = create(:role)
10
+ variant.volume_prices.create! amount: 9, discount_type: 'price', range: '(2+)'
11
+ order.contents.add(variant, 1)
9
12
  end
10
13
 
11
14
  it 'updates the line item price when the quantity changes to match a range and has no role' do
12
- expect(@line_item.price.to_f).to be(10.00)
13
- @order.contents.add(@variant, 1)
14
- expect(@order.line_items.first.price.to_f).to be(9.00)
15
+ expect(line_item.price.to_f).to be(10.00)
16
+ order.contents.add(variant, 1)
17
+ expect(order.line_items.first.price.to_f).to be(9.00)
15
18
  end
16
19
 
17
20
  it 'updates the line item price when the quantity changes to match a range and role matches' do
18
- @order.user.spree_roles << @role
19
- Spree::Config.volume_pricing_role = @role.name
20
- expect(@order.user.has_spree_role? @role.name.to_sym).to be(true)
21
- @variant.volume_prices.first.update(role_id: @role.id)
22
- expect(@line_item.price.to_f).to be(10.00)
23
- @order.contents.add(@variant, 1)
24
- expect(@order.line_items.first.price.to_f).to be(9.00)
21
+ order.user.spree_roles << role
22
+ expect(order.user.has_spree_role?(role.name.to_sym)).to be(true)
23
+ variant.volume_prices.first.update(role_id: role.id)
24
+ expect(line_item.price.to_f).to be(10.00)
25
+ order.contents.add(variant, 1)
26
+ expect(order.line_items.first.price.to_f).to be(9.00)
25
27
  end
26
28
 
27
29
  it 'does not update the line item price when the variant role and order role don`t match' do
28
- expect(@order.user.has_spree_role? @role.name.to_sym).to be(false)
29
- @variant.volume_prices.first.update(role_id: @role.id)
30
- expect(@line_item.price.to_f).to be(10.00)
31
- @order.contents.add(@variant, 1)
32
- expect(@order.line_items.first.price.to_f).to be(10.00)
30
+ expect(order.user.has_spree_role?(role.name.to_sym)).to be(false)
31
+ variant.volume_prices.first.update(role_id: role.id)
32
+ expect(line_item.price.to_f).to be(10.00)
33
+ order.contents.add(variant, 1)
34
+ expect(order.line_items.first.price.to_f).to be(10.00)
33
35
  end
34
36
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  RSpec.describe Spree::Order, type: :model do
2
4
  before do
3
5
  @order = create(:order)
@@ -31,7 +33,7 @@ RSpec.describe Spree::Order, type: :model do
31
33
  end
32
34
 
33
35
  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
36
+ stub_spree_preferences(use_master_variant_volume_pricing: true)
35
37
  @master = @variant.product.master
36
38
  @master.volume_prices << create(:volume_price, range: '(1..5)', amount: 9, position: 2)
37
39
  @order.contents.add(@variant, 5)
@@ -39,7 +41,7 @@ RSpec.describe Spree::Order, type: :model do
39
41
  end
40
42
 
41
43
  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
44
+ stub_spree_preferences(use_master_variant_volume_pricing: false)
43
45
  @master = @variant.product.master
44
46
  @master.volume_prices << create(:volume_price, range: '(1..5)', amount: 9, position: 2)
45
47
  @order.contents.add(@variant, 5)
@@ -1,306 +1,6 @@
1
+ # frozen_string_literal: true
2
+
1
3
  RSpec.describe Spree::Variant, type: :model do
2
4
  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
5
+ it { is_expected.to have_many(:model_volume_prices) }
306
6
  end
@@ -1,120 +1,215 @@
1
+ # frozen_string_literal: true
2
+
1
3
  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') }
4
+ let(:volume_price) do
5
+ described_class.new(variant: Spree::Variant.new, amount: 10, discount_type: 'price')
6
+ end
7
+
8
+ it { is_expected.to belong_to(:variant).touch(true).optional }
9
+ it { is_expected.to belong_to(:volume_price_model).touch(true).optional }
10
+ it { is_expected.to belong_to(:spree_role).class_name('Spree::Role').with_foreign_key('role_id').optional }
5
11
  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
12
  it { is_expected.to validate_presence_of(:amount) }
8
13
 
9
- before do
10
- @volume_price = Spree::VolumePrice.new(variant: Spree::Variant.new, amount: 10, discount_type: 'price')
11
- end
14
+ it { is_expected.to validate_inclusion_of(:discount_type).in_array(%w[price dollar percent]) }
15
+
16
+ describe '.for_variant' do
17
+ subject { described_class.for_variant(variant, user: user) }
18
+
19
+ let(:user) { nil }
20
+ let(:variant) { create(:variant) }
21
+ let!(:volume_prices) { create_list(:volume_price, 2, variant: variant) }
12
22
 
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
23
+ context 'if no user is given' do
24
+ it 'returns all volume prices for given variant that are not related to a specific role' do
25
+ expect(subject).to eq(volume_prices)
26
+ end
17
27
  end
18
- end
19
28
 
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
29
+ context 'if user is given' do
30
+ let(:role) do
31
+ create(:role, name: 'merchant')
32
+ end
33
+
34
+ let(:user) do
35
+ create(:user)
36
+ end
37
+
38
+ let!(:volume_prices_for_user_role) do
39
+ create_list(:volume_price, 2, variant: variant, role_id: role.id)
40
+ end
41
+
42
+ context 'whose role matches' do
43
+ before do
44
+ user.spree_roles = [role]
45
+ end
46
+
47
+ it 'returns role specific volume prices' do
48
+ expect(subject).to include(*volume_prices_for_user_role)
49
+ end
50
+
51
+ it 'returns non-role specific volume prices' do
52
+ expect(subject).to include(*volume_prices)
53
+ end
54
+ end
55
+
56
+ context 'whose role does not match' do
57
+ before do
58
+ user.spree_roles = []
59
+ end
60
+
61
+ it 'does not include role specific volume prices' do
62
+ expect(subject).not_to include(*volume_prices_for_user_role)
63
+ end
64
+
65
+ it 'returns non-role specific volume prices' do
66
+ expect(subject).to include(*volume_prices)
67
+ end
68
+ end
69
+ end
70
+
71
+ context 'if volume prices are not related to the variant but to a volume price model' do
72
+ let(:volume_price_model) do
73
+ create(:volume_price_model)
74
+ end
75
+
76
+ let!(:volume_prices_from_model) do
77
+ create_list(:volume_price, 2, volume_price_model: volume_price_model, variant: nil)
78
+ end
79
+
80
+ context 'and these volume prices are also related to the given variant' do
81
+ let(:variant) do
82
+ create(:variant, volume_price_models: [volume_price_model])
83
+ end
84
+
85
+ it 'includes these volume prices' do
86
+ expect(subject).to include(*volume_prices_from_model)
87
+ end
88
+ end
89
+
90
+ context 'and these volume prices are not related to the given variant' do
91
+ it 'does not include these volume prices' do
92
+ expect(subject).not_to include(*volume_prices_from_model)
93
+ end
94
+ end
24
95
  end
25
96
  end
26
97
 
27
98
  describe 'valid range format' do
28
99
  it 'requires the presence of a variant' do
29
- @volume_price.variant = nil
30
- expect(@volume_price).not_to be_valid
100
+ volume_price.variant = nil
101
+ expect(volume_price).not_to be_valid
31
102
  end
32
103
 
33
104
  it 'consider a range of (1..2) to be valid' do
34
- @volume_price.range = '(1..2)'
35
- expect(@volume_price).to be_valid
105
+ volume_price.range = '(1..2)'
106
+ expect(volume_price).to be_valid
36
107
  end
37
108
 
38
109
  it 'consider a range of (1...2) to be valid' do
39
- @volume_price.range = '(1...2)'
40
- expect(@volume_price).to be_valid
110
+ volume_price.range = '(1...2)'
111
+ expect(volume_price).to be_valid
41
112
  end
42
113
 
43
114
  it 'consider a range of 1..2 to be valid' do
44
- @volume_price.range = '1..2'
45
- expect(@volume_price).to be_valid
115
+ volume_price.range = '1..2'
116
+ expect(volume_price).to be_valid
46
117
  end
47
118
 
48
119
  it 'consider a range of 1...2 to be valid' do
49
- @volume_price.range = '1...2'
50
- expect(@volume_price).to be_valid
120
+ volume_price.range = '1...2'
121
+ expect(volume_price).to be_valid
51
122
  end
52
123
 
53
124
  it 'consider a range of (10+) to be valid' do
54
- @volume_price.range = '(10+)'
55
- expect(@volume_price).to be_valid
125
+ volume_price.range = '(10+)'
126
+ expect(volume_price).to be_valid
56
127
  end
57
128
 
58
129
  it 'consider a range of 10+ to be valid' do
59
- @volume_price.range = '10+'
60
- expect(@volume_price).to be_valid
130
+ volume_price.range = '10+'
131
+ expect(volume_price).to be_valid
61
132
  end
62
133
 
63
134
  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
135
+ volume_price.range = '1-2'
136
+ expect(volume_price).not_to be_valid
66
137
  end
67
138
 
68
139
  it 'does not consider a range of 1 to valid' do
69
- @volume_price.range = '1'
70
- expect(@volume_price).not_to be_valid
140
+ volume_price.range = '1'
141
+ expect(volume_price).not_to be_valid
71
142
  end
72
143
 
73
144
  it 'does not consider a range of foo to valid' do
74
- @volume_price.range = 'foo'
75
- expect(@volume_price).not_to be_valid
145
+ volume_price.range = 'foo'
146
+ expect(volume_price).not_to be_valid
147
+ end
148
+ end
149
+
150
+ describe 'display_range' do
151
+ subject(:display_range) { volume_price.display_range }
152
+
153
+ let(:volume_price) { described_class.new(range: range) }
154
+
155
+ context 'with parens' do
156
+ let(:range) { '(48+)' }
157
+
158
+ it { is_expected.to eq('48+') }
159
+ end
160
+
161
+ context 'with range dots' do
162
+ let(:range) { '1..3' }
163
+
164
+ it { is_expected.to eq('1-3') }
165
+ end
166
+
167
+ context 'with range dots and parens' do
168
+ let(:range) { '(1..3)' }
169
+
170
+ it { is_expected.to eq('1-3') }
76
171
  end
77
172
  end
78
173
 
79
174
  describe 'include?' do
80
175
  ['10..20', '(10..20)'].each do |range|
81
176
  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)
177
+ volume_price.range = range
178
+ expect(volume_price).not_to include(21)
84
179
  end
85
180
 
86
181
  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)
182
+ volume_price.range = range
183
+ expect(volume_price).to include(12)
89
184
  end
90
185
 
91
186
  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)
187
+ volume_price.range = range
188
+ expect(volume_price).to include(20)
94
189
  end
95
190
  end
96
191
 
97
192
  ['10...20', '(10...20)'].each do |range|
98
193
  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)
194
+ volume_price.range = range
195
+ expect(volume_price).not_to include(20)
101
196
  end
102
197
  end
103
198
 
104
199
  ['50+', '(50+)'].each do |range|
105
200
  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)
201
+ volume_price.range = range
202
+ expect(volume_price).to include(51)
108
203
  end
109
204
 
110
205
  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)
206
+ volume_price.range = range
207
+ expect(volume_price).to include(50)
113
208
  end
114
209
 
115
210
  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)
211
+ volume_price.range = range
212
+ expect(volume_price).not_to include(40)
118
213
  end
119
214
  end
120
215
  end