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.
Files changed (194) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/Gemfile +3 -0
  4. data/Rakefile +30 -0
  5. data/app/assets/javascripts/spree.js.coffee.erb +1 -1
  6. data/app/models/spree/ability.rb +1 -1
  7. data/app/models/spree/base.rb +3 -1
  8. data/app/models/spree/order_updater.rb +2 -1
  9. data/app/models/spree/price.rb +7 -12
  10. data/app/models/spree/product.rb +3 -2
  11. data/app/models/spree/reimbursement.rb +1 -1
  12. data/app/models/spree/state.rb +2 -0
  13. data/app/models/spree/zone.rb +1 -1
  14. data/lib/spree/core/version.rb +1 -1
  15. data/lib/spree/testing_support/shoulda_matcher_configuration.rb +6 -0
  16. data/script/rails +9 -0
  17. data/spec/fixtures/thinking-cat.jpg +0 -0
  18. data/spec/helpers/base_helper_spec.rb +137 -0
  19. data/spec/helpers/products_helper_spec.rb +224 -0
  20. data/spec/lib/calculated_adjustments_spec.rb +7 -0
  21. data/spec/lib/i18n_spec.rb +123 -0
  22. data/spec/lib/search/base_spec.rb +86 -0
  23. data/spec/lib/spree/core/controller_helpers/auth_spec.rb +101 -0
  24. data/spec/lib/spree/core/controller_helpers/order_spec.rb +95 -0
  25. data/spec/lib/spree/core/controller_helpers/search_spec.rb +17 -0
  26. data/spec/lib/spree/core/controller_helpers/store_spec.rb +16 -0
  27. data/spec/lib/spree/core/controller_helpers/strong_parameters_spec.rb +39 -0
  28. data/spec/lib/spree/core/delegate_belongs_to_spec.rb +22 -0
  29. data/spec/lib/spree/core/importer/order_spec.rb +502 -0
  30. data/spec/lib/spree/core/validators/email_spec.rb +53 -0
  31. data/spec/lib/spree/localized_number_spec.rb +38 -0
  32. data/spec/lib/spree/migrations_spec.rb +34 -0
  33. data/spec/lib/spree/money_spec.rb +122 -0
  34. data/spec/lib/tasks/exchanges_spec.rb +136 -0
  35. data/spec/mailers/order_mailer_spec.rb +124 -0
  36. data/spec/mailers/reimbursement_mailer_spec.rb +47 -0
  37. data/spec/mailers/shipment_mailer_spec.rb +63 -0
  38. data/spec/mailers/test_mailer_spec.rb +24 -0
  39. data/spec/models/spree/ability_spec.rb +246 -0
  40. data/spec/models/spree/address_spec.rb +291 -0
  41. data/spec/models/spree/adjustable/adjustments_updater_spec.rb +286 -0
  42. data/spec/models/spree/adjustment_spec.rb +163 -0
  43. data/spec/models/spree/app_configuration_spec.rb +23 -0
  44. data/spec/models/spree/asset_spec.rb +25 -0
  45. data/spec/models/spree/calculator/default_tax_spec.rb +127 -0
  46. data/spec/models/spree/calculator/flat_percent_item_total_spec.rb +25 -0
  47. data/spec/models/spree/calculator/flat_rate_spec.rb +47 -0
  48. data/spec/models/spree/calculator/flexi_rate_spec.rb +41 -0
  49. data/spec/models/spree/calculator/percent_on_line_item_spec.rb +15 -0
  50. data/spec/models/spree/calculator/price_sack_spec.rb +30 -0
  51. data/spec/models/spree/calculator/refunds/default_refund_amount_spec.rb +51 -0
  52. data/spec/models/spree/calculator/shipping.rb +8 -0
  53. data/spec/models/spree/calculator/shipping/flat_percent_item_total_spec.rb +23 -0
  54. data/spec/models/spree/calculator/shipping/flat_rate_spec.rb +13 -0
  55. data/spec/models/spree/calculator/shipping/flexi_rate_spec.rb +52 -0
  56. data/spec/models/spree/calculator/shipping/per_item_spec.rb +20 -0
  57. data/spec/models/spree/calculator/shipping/price_sack_spec.rb +29 -0
  58. data/spec/models/spree/calculator/tiered_flat_rate_spec.rb +40 -0
  59. data/spec/models/spree/calculator/tiered_percent_spec.rb +51 -0
  60. data/spec/models/spree/calculator_spec.rb +69 -0
  61. data/spec/models/spree/classification_spec.rb +93 -0
  62. data/spec/models/spree/concerns/display_money_spec.rb +43 -0
  63. data/spec/models/spree/country_spec.rb +18 -0
  64. data/spec/models/spree/credit_card_spec.rb +324 -0
  65. data/spec/models/spree/customer_return_spec.rb +262 -0
  66. data/spec/models/spree/exchange_spec.rb +75 -0
  67. data/spec/models/spree/gateway/bogus_simple.rb +20 -0
  68. data/spec/models/spree/gateway/bogus_spec.rb +13 -0
  69. data/spec/models/spree/gateway_spec.rb +54 -0
  70. data/spec/models/spree/image_spec.rb +5 -0
  71. data/spec/models/spree/inventory_unit_spec.rb +242 -0
  72. data/spec/models/spree/line_item_spec.rb +267 -0
  73. data/spec/models/spree/option_type_spec.rb +14 -0
  74. data/spec/models/spree/option_value_spec.rb +13 -0
  75. data/spec/models/spree/order/address_spec.rb +50 -0
  76. data/spec/models/spree/order/adjustments_spec.rb +29 -0
  77. data/spec/models/spree/order/callbacks_spec.rb +42 -0
  78. data/spec/models/spree/order/checkout_spec.rb +764 -0
  79. data/spec/models/spree/order/currency_updater_spec.rb +32 -0
  80. data/spec/models/spree/order/finalizing_spec.rb +117 -0
  81. data/spec/models/spree/order/helpers_spec.rb +5 -0
  82. data/spec/models/spree/order/payment_spec.rb +214 -0
  83. data/spec/models/spree/order/risk_assessment_spec.rb +84 -0
  84. data/spec/models/spree/order/shipments_spec.rb +43 -0
  85. data/spec/models/spree/order/state_machine_spec.rb +216 -0
  86. data/spec/models/spree/order/tax_spec.rb +84 -0
  87. data/spec/models/spree/order/totals_spec.rb +24 -0
  88. data/spec/models/spree/order/updating_spec.rb +18 -0
  89. data/spec/models/spree/order/validations_spec.rb +15 -0
  90. data/spec/models/spree/order_contents_spec.rb +256 -0
  91. data/spec/models/spree/order_inventory_spec.rb +228 -0
  92. data/spec/models/spree/order_merger_spec.rb +133 -0
  93. data/spec/models/spree/order_spec.rb +954 -0
  94. data/spec/models/spree/order_updater_spec.rb +283 -0
  95. data/spec/models/spree/payment/gateway_options_spec.rb +119 -0
  96. data/spec/models/spree/payment_method_spec.rb +95 -0
  97. data/spec/models/spree/payment_spec.rb +926 -0
  98. data/spec/models/spree/preference_spec.rb +80 -0
  99. data/spec/models/spree/preferences/configuration_spec.rb +30 -0
  100. data/spec/models/spree/preferences/preferable_spec.rb +348 -0
  101. data/spec/models/spree/preferences/scoped_store_spec.rb +58 -0
  102. data/spec/models/spree/preferences/store_spec.rb +46 -0
  103. data/spec/models/spree/price_spec.rb +42 -0
  104. data/spec/models/spree/product/scopes_spec.rb +148 -0
  105. data/spec/models/spree/product_duplicator_spec.rb +103 -0
  106. data/spec/models/spree/product_filter_spec.rb +26 -0
  107. data/spec/models/spree/product_option_type_spec.rb +5 -0
  108. data/spec/models/spree/product_property_spec.rb +11 -0
  109. data/spec/models/spree/product_spec.rb +474 -0
  110. data/spec/models/spree/promotion/actions/create_adjustment_spec.rb +50 -0
  111. data/spec/models/spree/promotion/actions/create_item_adjustments_spec.rb +148 -0
  112. data/spec/models/spree/promotion/actions/create_line_items_spec.rb +86 -0
  113. data/spec/models/spree/promotion/actions/free_shipping_spec.rb +36 -0
  114. data/spec/models/spree/promotion/rules/first_order_spec.rb +75 -0
  115. data/spec/models/spree/promotion/rules/item_total_spec.rb +282 -0
  116. data/spec/models/spree/promotion/rules/one_use_per_user_spec.rb +42 -0
  117. data/spec/models/spree/promotion/rules/option_value_spec.rb +90 -0
  118. data/spec/models/spree/promotion/rules/product_spec.rb +143 -0
  119. data/spec/models/spree/promotion/rules/taxon_spec.rb +102 -0
  120. data/spec/models/spree/promotion/rules/user_logged_in_spec.rb +27 -0
  121. data/spec/models/spree/promotion/rules/user_spec.rb +37 -0
  122. data/spec/models/spree/promotion_action_spec.rb +10 -0
  123. data/spec/models/spree/promotion_category_spec.rb +17 -0
  124. data/spec/models/spree/promotion_handler/cart_spec.rb +102 -0
  125. data/spec/models/spree/promotion_handler/coupon_spec.rb +323 -0
  126. data/spec/models/spree/promotion_handler/free_shipping_spec.rb +48 -0
  127. data/spec/models/spree/promotion_handler/page_spec.rb +44 -0
  128. data/spec/models/spree/promotion_rule_spec.rb +29 -0
  129. data/spec/models/spree/promotion_spec.rb +603 -0
  130. data/spec/models/spree/property_spec.rb +5 -0
  131. data/spec/models/spree/prototype_spec.rb +5 -0
  132. data/spec/models/spree/refund_spec.rb +195 -0
  133. data/spec/models/spree/reimbursement/credit_spec.rb +36 -0
  134. data/spec/models/spree/reimbursement/reimbursement_type_engine_spec.rb +140 -0
  135. data/spec/models/spree/reimbursement/reimbursement_type_validator_spec.rb +83 -0
  136. data/spec/models/spree/reimbursement_performer_spec.rb +30 -0
  137. data/spec/models/spree/reimbursement_spec.rb +215 -0
  138. data/spec/models/spree/reimbursement_tax_calculator_spec.rb +51 -0
  139. data/spec/models/spree/reimbursement_type/credit_spec.rb +53 -0
  140. data/spec/models/spree/reimbursement_type/exchange_spec.rb +46 -0
  141. data/spec/models/spree/reimbursement_type/original_payment_spec.rb +55 -0
  142. data/spec/models/spree/return_authorization_spec.rb +250 -0
  143. data/spec/models/spree/return_item/eligibility_validator/default_spec.rb +77 -0
  144. data/spec/models/spree/return_item/eligibility_validator/inventory_shipped_spec.rb +58 -0
  145. data/spec/models/spree/return_item/eligibility_validator/no_reimbursements_spec.rb +61 -0
  146. data/spec/models/spree/return_item/eligibility_validator/order_completed_spec.rb +32 -0
  147. data/spec/models/spree/return_item/eligibility_validator/rma_required_spec.rb +29 -0
  148. data/spec/models/spree/return_item/eligibility_validator/time_since_purchase_spec.rb +35 -0
  149. data/spec/models/spree/return_item/exchange_variant_eligibility/same_option_value_spec.rb +65 -0
  150. data/spec/models/spree/return_item/exchange_variant_eligibility/same_product_spec.rb +43 -0
  151. data/spec/models/spree/return_item_spec.rb +682 -0
  152. data/spec/models/spree/returns_calculator_spec.rb +14 -0
  153. data/spec/models/spree/shipment_spec.rb +740 -0
  154. data/spec/models/spree/shipping_calculator_spec.rb +45 -0
  155. data/spec/models/spree/shipping_category_spec.rb +5 -0
  156. data/spec/models/spree/shipping_method_spec.rb +88 -0
  157. data/spec/models/spree/shipping_rate_spec.rb +141 -0
  158. data/spec/models/spree/state_spec.rb +18 -0
  159. data/spec/models/spree/stock/availability_validator_spec.rb +36 -0
  160. data/spec/models/spree/stock/content_item_spec.rb +22 -0
  161. data/spec/models/spree/stock/coordinator_spec.rb +51 -0
  162. data/spec/models/spree/stock/differentiator_spec.rb +39 -0
  163. data/spec/models/spree/stock/estimator_spec.rb +154 -0
  164. data/spec/models/spree/stock/inventory_unit_builder_spec.rb +38 -0
  165. data/spec/models/spree/stock/package_spec.rb +194 -0
  166. data/spec/models/spree/stock/packer_spec.rb +70 -0
  167. data/spec/models/spree/stock/prioritizer_spec.rb +125 -0
  168. data/spec/models/spree/stock/quantifier_spec.rb +97 -0
  169. data/spec/models/spree/stock/splitter/backordered_spec.rb +29 -0
  170. data/spec/models/spree/stock/splitter/base_spec.rb +21 -0
  171. data/spec/models/spree/stock/splitter/shipping_category_spec.rb +47 -0
  172. data/spec/models/spree/stock/splitter/weight_spec.rb +32 -0
  173. data/spec/models/spree/stock_item_spec.rb +410 -0
  174. data/spec/models/spree/stock_location_spec.rb +243 -0
  175. data/spec/models/spree/stock_movement_spec.rb +56 -0
  176. data/spec/models/spree/stock_transfer_spec.rb +50 -0
  177. data/spec/models/spree/store_spec.rb +50 -0
  178. data/spec/models/spree/tax_category_spec.rb +27 -0
  179. data/spec/models/spree/tax_rate_spec.rb +382 -0
  180. data/spec/models/spree/taxon_spec.rb +74 -0
  181. data/spec/models/spree/taxonomy_spec.rb +18 -0
  182. data/spec/models/spree/tracker_spec.rb +21 -0
  183. data/spec/models/spree/user_spec.rb +130 -0
  184. data/spec/models/spree/validations/db_maximum_length_validator_spec.rb +24 -0
  185. data/spec/models/spree/variant_spec.rb +523 -0
  186. data/spec/models/spree/zone_spec.rb +444 -0
  187. data/spec/spec_helper.rb +74 -0
  188. data/spec/support/big_decimal.rb +5 -0
  189. data/spec/support/concerns/adjustment_source_spec.rb +23 -0
  190. data/spec/support/concerns/default_price_spec.rb +28 -0
  191. data/spec/support/rake.rb +13 -0
  192. data/spec/support/test_gateway.rb +2 -0
  193. data/spree_core.gemspec +48 -0
  194. metadata +185 -4
@@ -0,0 +1,286 @@
1
+ require 'spec_helper'
2
+
3
+ module Spree
4
+ module Adjustable
5
+ describe AdjustmentsUpdater do
6
+ let(:order) { create :order_with_line_items, line_items_count: 1 }
7
+ let(:line_item) { order.line_items.first }
8
+
9
+ let(:subject) { AdjustmentsUpdater.new(line_item) }
10
+ let(:order_subject) { AdjustmentsUpdater.new(order) }
11
+
12
+ context '#update' do
13
+ it "updates a linked adjustment" do
14
+ tax_rate = create(:tax_rate, amount: 0.05)
15
+ create(:adjustment, order: order, source: tax_rate, adjustable: line_item)
16
+ line_item.price = 10
17
+ line_item.tax_category = tax_rate.tax_category
18
+
19
+ subject.update
20
+ expect(line_item.adjustment_total).to eq(0.5)
21
+ expect(line_item.additional_tax_total).to eq(0.5)
22
+ end
23
+ end
24
+
25
+ context "taxes and promotions" do
26
+ let!(:tax_rate) do
27
+ create(:tax_rate, amount: 0.05)
28
+ end
29
+
30
+ let!(:promotion) do
31
+ Spree::Promotion.create(name: "$10 off")
32
+ end
33
+
34
+ let!(:promotion_action) do
35
+ calculator = Calculator::FlatRate.new(preferred_amount: 10)
36
+ Promotion::Actions::CreateItemAdjustments.create(calculator: calculator,
37
+ promotion: promotion)
38
+ end
39
+
40
+ before do
41
+ line_item.price = 20
42
+ line_item.tax_category = tax_rate.tax_category
43
+ line_item.save
44
+ create(:adjustment, order: order, source: promotion_action, adjustable: line_item)
45
+ end
46
+
47
+ context "tax included in price" do
48
+ before do
49
+ create(:adjustment, source: tax_rate,
50
+ adjustable: line_item,
51
+ order: order,
52
+ included: true)
53
+ end
54
+
55
+ it "tax has no bearing on final price" do
56
+ subject.update
57
+ line_item.reload
58
+ expect(line_item.included_tax_total).to eq(0.5)
59
+ expect(line_item.additional_tax_total).to eq(0)
60
+ expect(line_item.promo_total).to eq(-10)
61
+ expect(line_item.adjustment_total).to eq(-10)
62
+ end
63
+
64
+ it "tax linked to order" do
65
+ order_subject.update
66
+ order.reload
67
+ expect(order.included_tax_total).to eq(0.5)
68
+ expect(order.additional_tax_total).to eq(00)
69
+ end
70
+ end
71
+
72
+ context "tax excluded from price" do
73
+ before do
74
+ create(:adjustment, source: tax_rate,
75
+ adjustable: line_item,
76
+ order: order,
77
+ included: false)
78
+ end
79
+
80
+ it "tax applies to line item" do
81
+ subject.update
82
+ line_item.reload
83
+ # Taxable amount is: $20 (base) - $10 (promotion) = $10
84
+ # Tax rate is 5% (of $10).
85
+ expect(line_item.included_tax_total).to eq(0)
86
+ expect(line_item.additional_tax_total).to eq(0.5)
87
+ expect(line_item.promo_total).to eq(-10)
88
+ expect(line_item.adjustment_total).to eq(-9.5)
89
+ end
90
+
91
+ it "tax linked to order" do
92
+ order_subject.update
93
+ order.reload
94
+ expect(order.included_tax_total).to eq(0)
95
+ expect(order.additional_tax_total).to eq(0.5)
96
+ end
97
+ end
98
+ end
99
+
100
+ context "best promotion is always applied" do
101
+ let(:calculator) { Calculator::FlatRate.new(preferred_amount: 10) }
102
+
103
+ let(:source) { Promotion::Actions::CreateItemAdjustments.create calculator: calculator }
104
+
105
+ def create_adjustment(label, amount)
106
+ create(:adjustment, order: order,
107
+ adjustable: line_item,
108
+ source: source,
109
+ amount: amount,
110
+ state: "closed",
111
+ label: label,
112
+ mandatory: false)
113
+ end
114
+
115
+ it "should make all but the most valuable promotion adjustment ineligible, " +
116
+ "leaving non promotion adjustments alone" do
117
+ create_adjustment("Promotion A", -100)
118
+ create_adjustment("Promotion B", -200)
119
+ create_adjustment("Promotion C", -300)
120
+ create(:adjustment, order: order,
121
+ adjustable: line_item,
122
+ source: nil,
123
+ amount: -500,
124
+ state: "closed",
125
+ label: "Some other credit")
126
+ line_item.adjustments.each { |a| a.update_column(:eligible, true) }
127
+
128
+ subject.update
129
+
130
+ expect(line_item.adjustments.promotion.eligible.count).to eq(1)
131
+ expect(line_item.adjustments.promotion.eligible.first.label).to eq('Promotion C')
132
+ end
133
+
134
+ it "should choose the most recent promotion adjustment when amounts are equal" do
135
+ # Using Timecop is a regression test
136
+ Timecop.freeze do
137
+ create_adjustment("Promotion A", -200)
138
+ create_adjustment("Promotion B", -200)
139
+ end
140
+ line_item.adjustments.each { |a| a.update_column(:eligible, true) }
141
+
142
+ subject.update
143
+
144
+ expect(line_item.adjustments.promotion.eligible.count).to eq(1)
145
+ expect(line_item.adjustments.promotion.eligible.first.label).to eq('Promotion B')
146
+ end
147
+
148
+ context "when previously ineligible promotions become available" do
149
+ let(:order_promo1) do
150
+ create(:promotion,
151
+ :with_order_adjustment,
152
+ :with_item_total_rule,
153
+ weighted_order_adjustment_amount: 5,
154
+ item_total_threshold_amount: 10)
155
+ end
156
+
157
+ let(:order_promo2) do
158
+ create(:promotion,
159
+ :with_order_adjustment,
160
+ :with_item_total_rule,
161
+ weighted_order_adjustment_amount: 10,
162
+ item_total_threshold_amount: 20)
163
+ end
164
+
165
+ let(:order_promos) { [order_promo1, order_promo2] }
166
+
167
+ let(:line_item_promo1) do
168
+ create(:promotion,
169
+ :with_line_item_adjustment,
170
+ :with_item_total_rule,
171
+ adjustment_rate: 2.5,
172
+ item_total_threshold_amount: 10)
173
+ end
174
+
175
+ let(:line_item_promo2) do
176
+ create(:promotion,
177
+ :with_line_item_adjustment,
178
+ :with_item_total_rule,
179
+ adjustment_rate: 5,
180
+ item_total_threshold_amount: 20)
181
+ end
182
+
183
+ let(:line_item_promos) { [line_item_promo1, line_item_promo2] }
184
+ let(:order) { create(:order_with_line_items, line_items_count: 1) }
185
+
186
+ # Apply promotions in different sequences. Results should be the same.
187
+ promo_sequences = [[0, 1], [1, 0]]
188
+
189
+ promo_sequences.each do |promo_sequence|
190
+ it "should pick the best order-level promo according to current eligibility" do
191
+ # apply both promos to the order, even though only promo1 is eligible
192
+ order_promos[promo_sequence[0]].activate order: order
193
+ order_promos[promo_sequence[1]].activate order: order
194
+
195
+ order.reload
196
+ msg = "Expected two adjustments (using sequence #{promo_sequence})"
197
+ expect(order.all_adjustments.count).to eq(2), msg
198
+
199
+ msg = "Expected one elegible adjustment (using sequence #{promo_sequence})"
200
+ expect(order.all_adjustments.eligible.count).to eq(1), msg
201
+
202
+ msg = "Expected promo1 to be used (using sequence #{promo_sequence})"
203
+ expect(order.all_adjustments.eligible.first.source.promotion).to eq(order_promo1), msg
204
+
205
+ order.contents.add create(:variant, price: 10), 1
206
+ order.save
207
+
208
+ order.reload
209
+ msg = "Expected two adjustments (using sequence #{promo_sequence})"
210
+ expect(order.all_adjustments.count).to eq(2), msg
211
+
212
+ msg = "Expected one elegible adjustment (using sequence #{promo_sequence})"
213
+ expect(order.all_adjustments.eligible.count).to eq(1), msg
214
+
215
+ msg = "Expected promo2 to be used (using sequence #{promo_sequence})"
216
+ expect(order.all_adjustments.eligible.first.source.promotion).to eq(order_promo2), msg
217
+ end
218
+ end
219
+
220
+ promo_sequences.each do |promo_sequence|
221
+ it "should pick the best line-item-level promo according to current eligibility" do
222
+ # apply both promos to the order, even though only promo1 is eligible
223
+ line_item_promos[promo_sequence[0]].activate order: order
224
+ line_item_promos[promo_sequence[1]].activate order: order
225
+
226
+ order.reload
227
+ msg = "Expected one adjustment (using sequence #{promo_sequence})"
228
+ expect(order.all_adjustments.count).to eq(1), msg
229
+
230
+ msg = "Expected one elegible adjustment (using sequence #{promo_sequence})"
231
+ expect(order.all_adjustments.eligible.count).to eq(1), msg
232
+
233
+ # line_item_promo1 is the only one that has thus far met the order total threshold,
234
+ # it is the only promo which should be applied.
235
+ msg = "Expected line_item_promo1 to be used (using sequence #{promo_sequence})"
236
+ expect(order.all_adjustments.first.source.promotion).to eq(line_item_promo1), msg
237
+
238
+ order.contents.add create(:variant, price: 10), 1
239
+ order.save
240
+
241
+ order.reload
242
+ msg = "Expected four adjustments (using sequence #{promo_sequence})"
243
+ expect(order.all_adjustments.count).to eq(4), msg
244
+
245
+ msg = "Expected two elegible adjustments (using sequence #{promo_sequence})"
246
+ expect(order.all_adjustments.eligible.count).to eq(2), msg
247
+
248
+ order.all_adjustments.eligible.each do |adjustment|
249
+ msg = "Expected line_item_promo2 to be used (using sequence #{promo_sequence})"
250
+ expect(adjustment.source.promotion).to eq(line_item_promo2), msg
251
+ end
252
+ end
253
+ end
254
+ end
255
+
256
+ context "multiple adjustments and the best one is not eligible" do
257
+ let!(:promo_a) { create_adjustment("Promotion A", -100) }
258
+ let!(:promo_c) { create_adjustment("Promotion C", -300) }
259
+
260
+ before do
261
+ promo_a.update_column(:eligible, true)
262
+ promo_c.update_column(:eligible, false)
263
+ end
264
+
265
+ # regression for #3274
266
+ it "still makes the previous best eligible adjustment valid" do
267
+ subject.update
268
+ expect(line_item.adjustments.promotion.eligible.first.label).to eq('Promotion A')
269
+ end
270
+ end
271
+
272
+ it "should only leave one adjustment even if 2 have the same amount" do
273
+ create_adjustment("Promotion A", -100)
274
+ create_adjustment("Promotion B", -200)
275
+ create_adjustment("Promotion C", -200)
276
+
277
+ subject.update
278
+
279
+ expect(line_item.adjustments.promotion.eligible.count).to eq(1)
280
+ expect(line_item.adjustments.promotion.eligible.first.amount.to_i).to eq(-200)
281
+ end
282
+ end
283
+
284
+ end
285
+ end
286
+ end
@@ -0,0 +1,163 @@
1
+ # encoding: utf-8
2
+ #
3
+
4
+ require 'spec_helper'
5
+
6
+ describe Spree::Adjustment, :type => :model do
7
+
8
+ let(:order) { Spree::Order.new }
9
+
10
+ before do
11
+ allow(order).to receive(:update!)
12
+ end
13
+
14
+ let(:adjustment) { Spree::Adjustment.create!(label: 'Adjustment', adjustable: order, order: order, amount: 5) }
15
+
16
+ context '#create & #destroy' do
17
+ let(:adjustment) { Spree::Adjustment.new(label: "Adjustment", amount: 5, order: order, adjustable: create(:line_item)) }
18
+
19
+ it 'calls #update_adjustable_adjustment_total' do
20
+ expect(adjustment).to receive(:update_adjustable_adjustment_total).twice
21
+ adjustment.save
22
+ adjustment.destroy
23
+ end
24
+ end
25
+
26
+ context '#save' do
27
+ let(:order) { Spree::Order.create! }
28
+ let!(:adjustment) { Spree::Adjustment.create(label: "Adjustment", amount: 5, order: order, adjustable: order) }
29
+
30
+ it 'touches the adjustable' do
31
+ expect(adjustment.adjustable).to receive(:touch)
32
+ adjustment.amount = 3
33
+ adjustment.save
34
+ end
35
+ end
36
+
37
+ describe 'non_tax scope' do
38
+ subject do
39
+ Spree::Adjustment.non_tax.to_a
40
+ end
41
+
42
+ let!(:tax_adjustment) { create(:adjustment, order: order, source: create(:tax_rate)) }
43
+ let!(:non_tax_adjustment_with_source) { create(:adjustment, order: order, source_type: 'Spree::Order', source_id: nil) }
44
+ let!(:non_tax_adjustment_without_source) { create(:adjustment, order: order, source: nil) }
45
+
46
+ it 'select non-tax adjustments' do
47
+ expect(subject).to_not include tax_adjustment
48
+ expect(subject).to include non_tax_adjustment_with_source
49
+ expect(subject).to include non_tax_adjustment_without_source
50
+ end
51
+ end
52
+
53
+ describe 'competing_promos scope' do
54
+ before do
55
+ allow_any_instance_of(Spree::Adjustment).to receive(:update_adjustable_adjustment_total).and_return(true)
56
+ end
57
+
58
+ subject do
59
+ Spree::Adjustment.competing_promos.to_a
60
+ end
61
+
62
+ let!(:promotion_adjustment) { create(:adjustment, order: order, source_type: 'Spree::PromotionAction', source_id: nil) }
63
+ let!(:custom_adjustment_with_source) { create(:adjustment, order: order, source_type: 'Custom', source_id: nil) }
64
+ let!(:non_promotion_adjustment_with_source) { create(:adjustment, order: order, source_type: 'Spree::Order', source_id: nil) }
65
+ let!(:non_promotion_adjustment_without_source) { create(:adjustment, order: order, source: nil) }
66
+
67
+ context 'no custom source_types have been added to competing_promos' do
68
+ before { Spree::Adjustment.competing_promos_source_types = ['Spree::PromotionAction'] }
69
+
70
+ it 'selects promotion adjustments by default' do
71
+ expect(subject).to include promotion_adjustment
72
+ expect(subject).to_not include custom_adjustment_with_source
73
+ expect(subject).to_not include non_promotion_adjustment_with_source
74
+ expect(subject).to_not include non_promotion_adjustment_without_source
75
+ end
76
+ end
77
+
78
+ context 'a custom source_type has been added to competing_promos' do
79
+ before { Spree::Adjustment.competing_promos_source_types = ['Spree::PromotionAction', 'Custom'] }
80
+
81
+ it 'selects adjustments with registered source_types' do
82
+ expect(subject).to include promotion_adjustment
83
+ expect(subject).to include custom_adjustment_with_source
84
+ expect(subject).to_not include non_promotion_adjustment_with_source
85
+ expect(subject).to_not include non_promotion_adjustment_without_source
86
+ end
87
+ end
88
+ end
89
+
90
+
91
+ context "adjustment state" do
92
+ let(:adjustment) { create(:adjustment, order: order, state: 'open') }
93
+
94
+ context "#closed?" do
95
+ it "is true when adjustment state is closed" do
96
+ adjustment.state = "closed"
97
+ expect(adjustment).to be_closed
98
+ end
99
+
100
+ it "is false when adjustment state is open" do
101
+ adjustment.state = "open"
102
+ expect(adjustment).to_not be_closed
103
+ end
104
+ end
105
+ end
106
+
107
+ context '#currency' do
108
+ it 'returns the globally configured currency' do
109
+ expect(adjustment.currency).to eq 'USD'
110
+ end
111
+ end
112
+
113
+ context "#display_amount" do
114
+ before { adjustment.amount = 10.55 }
115
+
116
+ it "shows the amount" do
117
+ expect(adjustment.display_amount.to_s).to eq "$10.55"
118
+ end
119
+
120
+ context "with currency set to JPY" do
121
+ context "when adjustable is set to an order" do
122
+ before do
123
+ expect(order).to receive(:currency).and_return('JPY')
124
+ adjustment.adjustable = order
125
+ end
126
+
127
+ it "displays in JPY" do
128
+ expect(adjustment.display_amount.to_s).to eq "¥11"
129
+ end
130
+ end
131
+
132
+ context "when adjustable is nil" do
133
+ it "displays in the default currency" do
134
+ expect(adjustment.display_amount.to_s).to eq "$10.55"
135
+ end
136
+ end
137
+ end
138
+ end
139
+
140
+ context '#update!' do
141
+ context "when adjustment is closed" do
142
+ before { expect(adjustment).to receive(:closed?).and_return(true) }
143
+
144
+ it "does not update the adjustment" do
145
+ expect(adjustment).to_not receive(:update_column)
146
+ adjustment.update!
147
+ end
148
+ end
149
+
150
+ context "when adjustment is open" do
151
+ before { expect(adjustment).to receive(:closed?).and_return(false) }
152
+
153
+ it "updates the amount" do
154
+ expect(adjustment).to receive(:adjustable).and_return(double("Adjustable")).at_least(1).times
155
+ expect(adjustment).to receive(:source).and_return(double("Source")).at_least(1).times
156
+ expect(adjustment.source).to receive("compute_amount").with(adjustment.adjustable).and_return(5)
157
+ expect(adjustment).to receive(:update_columns).with(amount: 5, updated_at: kind_of(Time))
158
+ adjustment.update!
159
+ end
160
+ end
161
+ end
162
+
163
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::AppConfiguration, :type => :model do
4
+
5
+ let (:prefs) { Rails.application.config.spree.preferences }
6
+
7
+ it "should be available from the environment" do
8
+ prefs.layout = "my/layout"
9
+ expect(prefs.layout).to eq "my/layout"
10
+ end
11
+
12
+ it "should be available as Spree::Config for legacy access" do
13
+ Spree::Config.layout = "my/layout"
14
+ expect(Spree::Config.layout).to eq "my/layout"
15
+ end
16
+
17
+ it "uses base searcher class by default" do
18
+ prefs.searcher_class = nil
19
+ expect(prefs.searcher_class).to eq Spree::Core::Search::Base
20
+ end
21
+
22
+ end
23
+