solidus_core 2.0.3 → 2.1.0.beta1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


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

Files changed (187) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +62 -3
  3. data/app/assets/javascripts/spree.js.coffee.erb +4 -1
  4. data/app/helpers/spree/base_helper.rb +7 -48
  5. data/app/models/spree/address.rb +5 -1
  6. data/app/models/spree/adjustment.rb +3 -3
  7. data/app/models/spree/app_configuration.rb +13 -0
  8. data/app/models/spree/calculator.rb +3 -2
  9. data/app/models/spree/calculator/default_tax.rb +6 -10
  10. data/app/models/spree/calculator/flat_percent_item_total.rb +0 -4
  11. data/app/models/spree/calculator/flat_rate.rb +0 -4
  12. data/app/models/spree/calculator/flexi_rate.rb +0 -4
  13. data/app/models/spree/calculator/free_shipping.rb +0 -3
  14. data/app/models/spree/calculator/percent_on_line_item.rb +0 -4
  15. data/app/models/spree/calculator/percent_per_item.rb +0 -4
  16. data/app/models/spree/calculator/price_sack.rb +0 -4
  17. data/app/models/spree/calculator/returns/default_refund_amount.rb +0 -3
  18. data/app/models/spree/calculator/shipping/flat_percent_item_total.rb +0 -4
  19. data/app/models/spree/calculator/shipping/flat_rate.rb +0 -4
  20. data/app/models/spree/calculator/shipping/flexi_rate.rb +0 -4
  21. data/app/models/spree/calculator/shipping/per_item.rb +0 -4
  22. data/app/models/spree/calculator/shipping/price_sack.rb +0 -4
  23. data/app/models/spree/calculator/tiered_flat_rate.rb +0 -4
  24. data/app/models/spree/calculator/tiered_percent.rb +0 -4
  25. data/app/models/spree/credit_card.rb +27 -14
  26. data/app/models/spree/gateway.rb +4 -0
  27. data/app/models/spree/inventory_unit.rb +2 -0
  28. data/app/models/spree/line_item.rb +31 -26
  29. data/app/models/spree/option_type.rb +0 -3
  30. data/app/models/spree/order.rb +28 -31
  31. data/app/models/spree/order/checkout.rb +0 -2
  32. data/app/models/spree/order_contents.rb +0 -45
  33. data/app/models/spree/order_merger.rb +6 -6
  34. data/app/models/spree/order_update_attributes.rb +0 -2
  35. data/app/models/spree/order_updater.rb +91 -13
  36. data/app/models/spree/payment.rb +9 -2
  37. data/app/models/spree/payment/processing.rb +15 -9
  38. data/app/models/spree/payment_method.rb +48 -5
  39. data/app/models/spree/price.rb +7 -9
  40. data/app/models/spree/product.rb +1 -25
  41. data/app/models/spree/promotion.rb +22 -14
  42. data/app/models/spree/promotion/actions/create_adjustment.rb +12 -1
  43. data/app/models/spree/promotion/actions/create_item_adjustments.rb +15 -1
  44. data/app/models/spree/promotion/actions/create_quantity_adjustments.rb +5 -3
  45. data/app/models/spree/promotion/actions/free_shipping.rb +14 -0
  46. data/app/models/spree/promotion/rules/taxon.rb +7 -2
  47. data/app/models/spree/promotion/rules/user_role.rb +43 -0
  48. data/app/models/spree/promotion_action.rb +19 -2
  49. data/app/models/spree/promotion_handler/coupon.rb +1 -4
  50. data/app/models/spree/promotion_handler/free_shipping.rb +22 -17
  51. data/app/models/spree/promotion_rule_role.rb +6 -0
  52. data/app/models/spree/property.rb +0 -3
  53. data/app/models/spree/return_authorization.rb +2 -0
  54. data/app/models/spree/shipment.rb +5 -21
  55. data/app/models/spree/shipping_method.rb +23 -2
  56. data/app/models/spree/shipping_rate.rb +3 -0
  57. data/app/models/spree/stock/estimator.rb +1 -1
  58. data/app/models/spree/stock_location.rb +3 -0
  59. data/app/models/spree/store.rb +7 -0
  60. data/app/models/spree/tax/item_adjuster.rb +27 -12
  61. data/app/models/spree/tax/order_adjuster.rb +2 -5
  62. data/app/models/spree/tax/tax_helpers.rb +4 -8
  63. data/app/models/spree/tax_rate.rb +1 -15
  64. data/app/models/spree/taxon.rb +0 -3
  65. data/app/models/spree/transfer_item.rb +1 -1
  66. data/app/models/spree/user_class_handle.rb +14 -9
  67. data/app/models/spree/variant/pricing_options.rb +1 -1
  68. data/app/models/spree/wallet/add_payment_sources_to_wallet.rb +1 -1
  69. data/app/models/spree/zone.rb +20 -13
  70. data/config/locales/en.yml +144 -62
  71. data/db/migrate/20120831092320_spree_one_two.rb +0 -7
  72. data/db/migrate/20150723224133_remove_unnecessary_indexes.rb +0 -2
  73. data/db/migrate/20160924135758_remove_is_default_from_prices.rb +5 -0
  74. data/db/migrate/20161009141333_remove_currency_from_line_items.rb +5 -0
  75. data/db/migrate/20161014221052_add_available_to_columns_and_remove_display_on_from_payment_methods.rb +28 -0
  76. data/db/migrate/20161123154034_add_available_to_users_and_remove_display_on_from_shipping_methods.rb +20 -0
  77. data/lib/generators/spree/custom_user/templates/authentication_helpers.rb.tt +4 -0
  78. data/lib/generators/spree/dummy/dummy_generator.rb +0 -2
  79. data/lib/spree/core.rb +0 -5
  80. data/lib/spree/core/controller_helpers/pricing.rb +2 -1
  81. data/lib/spree/core/engine.rb +14 -0
  82. data/lib/spree/core/version.rb +1 -1
  83. data/lib/spree/deprecation.rb +1 -1
  84. data/lib/spree/localized_number.rb +3 -2
  85. data/lib/spree/permission_sets/configuration_display.rb +0 -1
  86. data/lib/spree/permission_sets/configuration_management.rb +0 -1
  87. data/lib/spree/permission_sets/product_display.rb +0 -1
  88. data/lib/spree/permission_sets/product_management.rb +0 -1
  89. data/lib/spree/permission_sets/user_management.rb +2 -4
  90. data/lib/spree/permitted_attributes.rb +3 -2
  91. data/lib/spree/testing_support/capybara_ext.rb +0 -12
  92. data/lib/spree/testing_support/factories/address_factory.rb +1 -1
  93. data/lib/spree/testing_support/factories/line_item_factory.rb +0 -1
  94. data/lib/spree/testing_support/factories/payment_factory.rb +4 -0
  95. data/lib/spree/testing_support/factories/payment_method_factory.rb +8 -1
  96. data/lib/spree/testing_support/factories/user_factory.rb +2 -2
  97. data/solidus_core.gemspec +4 -3
  98. data/spec/helpers/base_helper_spec.rb +0 -40
  99. data/spec/lib/spree/core/controller_helpers/pricing_spec.rb +16 -0
  100. data/spec/lib/spree/core/importer/order_spec.rb +27 -18
  101. data/spec/lib/spree/core/price_migrator_spec.rb +3 -1
  102. data/spec/lib/spree/core/testing_support/factories/order_factory_spec.rb +16 -0
  103. data/spec/lib/spree/core/unreturned_item_charger_spec.rb +0 -2
  104. data/spec/lib/tasks/exchanges_spec.rb +4 -2
  105. data/spec/lib/tasks/migrations/create_vat_prices_spec.rb +5 -3
  106. data/spec/models/spree/adjustment_spec.rb +136 -0
  107. data/spec/models/spree/calculator/default_tax_spec.rb +13 -7
  108. data/spec/models/spree/calculator/flat_percent_item_total_spec.rb +3 -0
  109. data/spec/models/spree/calculator/flat_rate_spec.rb +3 -0
  110. data/spec/models/spree/calculator/flexi_rate_spec.rb +3 -0
  111. data/spec/models/spree/calculator/free_shipping_spec.rb +6 -0
  112. data/spec/models/spree/calculator/percent_on_line_item_spec.rb +9 -4
  113. data/spec/models/spree/calculator/percent_per_item_spec.rb +10 -0
  114. data/spec/models/spree/calculator/price_sack_spec.rb +3 -0
  115. data/spec/models/spree/calculator/refunds/default_refund_amount_spec.rb +3 -0
  116. data/spec/models/spree/calculator/shipping/flat_percent_item_total_spec.rb +3 -0
  117. data/spec/models/spree/calculator/shipping/flat_rate_spec.rb +3 -0
  118. data/spec/models/spree/calculator/shipping/flexi_rate_spec.rb +3 -0
  119. data/spec/models/spree/calculator/shipping/per_item_spec.rb +3 -0
  120. data/spec/models/spree/calculator/shipping/price_sack_spec.rb +4 -1
  121. data/spec/models/spree/calculator/tiered_flat_rate_spec.rb +3 -0
  122. data/spec/models/spree/calculator/tiered_percent_spec.rb +3 -0
  123. data/spec/models/spree/credit_card_spec.rb +27 -1
  124. data/spec/models/spree/line_item_spec.rb +58 -65
  125. data/spec/models/spree/order/checkout_spec.rb +2 -1
  126. data/spec/models/spree/order/payment_spec.rb +9 -10
  127. data/spec/models/spree/order/tax_spec.rb +22 -7
  128. data/spec/models/spree/order/updating_spec.rb +1 -3
  129. data/spec/models/spree/order_cancellations_spec.rb +6 -4
  130. data/spec/models/spree/order_contents_spec.rb +34 -50
  131. data/spec/models/spree/order_inventory_spec.rb +3 -5
  132. data/spec/models/spree/order_merger_spec.rb +20 -0
  133. data/spec/models/spree/order_spec.rb +28 -64
  134. data/spec/models/spree/order_update_attributes_spec.rb +1 -5
  135. data/spec/models/spree/order_updater_spec.rb +251 -0
  136. data/spec/models/spree/payment_method_spec.rb +178 -28
  137. data/spec/models/spree/payment_spec.rb +35 -19
  138. data/spec/models/spree/permission_sets/configuration_display.rb +0 -4
  139. data/spec/models/spree/permission_sets/configuration_management_spec.rb +0 -2
  140. data/spec/models/spree/permission_sets/product_display_spec.rb +0 -4
  141. data/spec/models/spree/permission_sets/product_management_spec.rb +0 -2
  142. data/spec/models/spree/permission_sets/user_management_spec.rb +9 -2
  143. data/spec/models/spree/price_spec.rb +16 -1
  144. data/spec/models/spree/product_spec.rb +0 -75
  145. data/spec/models/spree/promotion/actions/create_adjustment_spec.rb +20 -0
  146. data/spec/models/spree/promotion/actions/create_item_adjustments_spec.rb +39 -15
  147. data/spec/models/spree/promotion/actions/create_quantity_adjustments_spec.rb +203 -22
  148. data/spec/models/spree/promotion/actions/free_shipping_spec.rb +22 -3
  149. data/spec/models/spree/promotion/rules/taxon_spec.rb +26 -0
  150. data/spec/models/spree/promotion/rules/user_role_spec.rb +86 -0
  151. data/spec/models/spree/promotion_action_spec.rb +38 -0
  152. data/spec/models/spree/promotion_handler/coupon_spec.rb +36 -33
  153. data/spec/models/spree/promotion_handler/free_shipping_spec.rb +21 -22
  154. data/spec/models/spree/promotion_spec.rb +46 -6
  155. data/spec/models/spree/reimbursement_spec.rb +1 -1
  156. data/spec/models/spree/reimbursement_tax_calculator_spec.rb +2 -2
  157. data/spec/models/spree/shipment_spec.rb +68 -50
  158. data/spec/models/spree/shipping_method_spec.rb +41 -0
  159. data/spec/models/spree/shipping_rate_spec.rb +9 -3
  160. data/spec/models/spree/stock/estimator_spec.rb +4 -2
  161. data/spec/models/spree/store_credit_spec.rb +3 -3
  162. data/spec/models/spree/tax/item_adjuster_spec.rb +31 -21
  163. data/spec/models/spree/tax/order_adjuster_spec.rb +6 -10
  164. data/spec/models/spree/tax/taxation_integration_spec.rb +19 -0
  165. data/spec/models/spree/tax_rate_spec.rb +5 -26
  166. data/spec/models/spree/transfer_item_spec.rb +11 -0
  167. data/spec/models/spree/variant/pricing_options_spec.rb +7 -17
  168. data/spec/models/spree/variant_spec.rb +2 -4
  169. data/spec/models/spree/zone_spec.rb +60 -20
  170. data/spec/shared_examples/calculator_shared_examples.rb +8 -0
  171. metadata +19 -24
  172. data/app/models/spree/item_adjustments.rb +0 -89
  173. data/app/models/spree/option_type_prototype.rb +0 -6
  174. data/app/models/spree/property_prototype.rb +0 -6
  175. data/app/models/spree/prototype.rb +0 -14
  176. data/app/models/spree/prototype_taxon.rb +0 -6
  177. data/app/models/spree/tracker.rb +0 -8
  178. data/db/migrate/20150128032538_remove_environment_from_tracker.rb +0 -6
  179. data/lib/generators/spree/dummy/templates/initializers/custom_user.rb +0 -1
  180. data/lib/spree/core/delegate_belongs_to.rb +0 -94
  181. data/lib/spree/testing_support/factories/prototype_factory.rb +0 -8
  182. data/lib/spree/testing_support/factories/tracker_factory.rb +0 -6
  183. data/spec/lib/spree/core/delegate_belongs_to_spec.rb +0 -24
  184. data/spec/lib/spree/core/testing_support/factories/prototype_factory_spec.rb +0 -12
  185. data/spec/lib/spree/core/testing_support/factories/tracker_factory_spec.rb +0 -12
  186. data/spec/models/spree/item_adjustments_spec.rb +0 -306
  187. data/spec/models/spree/tracker_spec.rb +0 -21
@@ -2,10 +2,11 @@ require 'spec_helper'
2
2
 
3
3
  describe Spree::Promotion::Actions::FreeShipping, type: :model do
4
4
  let(:order) { create(:completed_order_with_totals) }
5
- let(:promotion_code) { create(:promotion_code, value: 'somecode') }
6
- let(:promotion) { promotion_code.promotion }
7
- let(:action) { Spree::Promotion::Actions::FreeShipping.create }
5
+ let(:shipment) { order.shipments.to_a.first }
6
+ let(:promotion) { create(:promotion, code: 'somecode', promotion_actions: [action]) }
7
+ let(:action) { Spree::Promotion::Actions::FreeShipping.new }
8
8
  let(:payload) { { order: order, promotion_code: promotion_code } }
9
+ let(:promotion_code) { promotion.codes.first! }
9
10
 
10
11
  # From promotion spec:
11
12
  context "#perform" do
@@ -37,4 +38,22 @@ describe Spree::Promotion::Actions::FreeShipping, type: :model do
37
38
  end
38
39
  end
39
40
  end
41
+
42
+ describe '#remove_from' do
43
+ # this adjustment should not get removed
44
+ let!(:other_adjustment) { create(:adjustment, adjustable: shipment, order: order, source: nil) }
45
+
46
+ before do
47
+ action.perform(payload)
48
+ @action_adjustment = shipment.adjustments.where(source: action).first!
49
+ end
50
+
51
+ it 'removes the action adjustment' do
52
+ expect(shipment.adjustments).to match_array([other_adjustment, @action_adjustment])
53
+
54
+ action.remove_from(order)
55
+
56
+ expect(shipment.adjustments).to eq([other_adjustment])
57
+ end
58
+ end
40
59
  end
@@ -97,6 +97,32 @@ describe Spree::Promotion::Rules::Taxon, type: :model do
97
97
  end
98
98
  end
99
99
 
100
+ context 'with none match policy' do
101
+ before do
102
+ rule.preferred_match_policy = 'none'
103
+ end
104
+
105
+ context "none of the order's products are in listed taxon" do
106
+ before { rule.taxons << taxon2 }
107
+ it { expect(rule).to be_eligible(order) }
108
+ end
109
+
110
+ context "one of the order's products is in a listed taxon" do
111
+ before do
112
+ order.products.first.taxons << taxon
113
+ rule.taxons << taxon
114
+ end
115
+ it "should not be eligible" do
116
+ expect(rule).not_to be_eligible(order)
117
+ end
118
+ it "sets an error message" do
119
+ rule.eligible?(order)
120
+ expect(rule.eligibility_errors.full_messages.first).
121
+ to eq "Your cart contains a product from an excluded category that prevents this coupon code from being applied."
122
+ end
123
+ end
124
+ end
125
+
100
126
  context 'with an invalid match policy' do
101
127
  before do
102
128
  order.products.first.taxons << taxon
@@ -0,0 +1,86 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Promotion::Rules::UserRole, type: :model do
4
+ let(:rule) { described_class.new(preferred_role_ids: roles_for_rule) }
5
+ let(:user) { create(:user, spree_roles: roles_for_user) }
6
+ let(:roles_for_rule) { [] }
7
+ let(:roles_for_user) { [] }
8
+
9
+ subject { rule }
10
+
11
+ shared_examples 'eligibility' do
12
+ context 'no roles on rule' do
13
+ let(:roles_for_user) { [create(:role)] }
14
+ it 'should not be eligible' do
15
+ expect(rule).to_not be_eligible(order)
16
+ end
17
+ end
18
+
19
+ context 'no roles on user' do
20
+ let(:roles_for_rule) { [create(:role)] }
21
+ it 'should not be eligible' do
22
+ expect(rule).to_not be_eligible(order)
23
+ end
24
+ end
25
+
26
+ context 'mismatched roles' do
27
+ let(:roles_for_user) { [create(:role)] }
28
+ let(:roles_for_rule) { [create(:role)] }
29
+ it 'should not be eligible' do
30
+ expect(rule).to_not be_eligible(order)
31
+ end
32
+ end
33
+
34
+ context 'matching all roles' do
35
+ let(:roles_for_user) { [create(:role), create(:role)] }
36
+ let(:roles_for_rule) { roles_for_user }
37
+ it 'should be eligible' do
38
+ expect(rule).to be_eligible(order)
39
+ end
40
+ end
41
+ end
42
+
43
+ context '#eligible?(order)' do
44
+ context 'order with no user' do
45
+ let(:order) { Spree::Order.new }
46
+
47
+ it 'should not be eligible' do
48
+ expect(rule).to_not be_eligible(order)
49
+ end
50
+ end
51
+
52
+ context 'order with user' do
53
+ let(:order) { Spree::Order.new(user: user) }
54
+
55
+ context 'with any match policy' do
56
+ before { rule.preferred_match_policy = 'any' }
57
+
58
+ include_examples 'eligibility'
59
+
60
+ context 'one shared role' do
61
+ let(:shared_role) { create(:role) }
62
+ let(:roles_for_user) { [create(:role), shared_role] }
63
+ let(:roles_for_rule) { [create(:role), shared_role] }
64
+ it 'should be eligible' do
65
+ expect(rule).to be_eligible(order)
66
+ end
67
+ end
68
+ end
69
+
70
+ context 'with all match policy' do
71
+ before { rule.preferred_match_policy = 'all' }
72
+
73
+ include_examples 'eligibility'
74
+
75
+ context 'one shared role' do
76
+ let(:shared_role) { create(:role) }
77
+ let(:roles_for_user) { [create(:role), shared_role] }
78
+ let(:roles_for_rule) { [create(:role), shared_role] }
79
+ it 'should not be eligible' do
80
+ expect(rule).to_not be_eligible(order)
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::PromotionAction, type: :model do
4
+ describe '#remove_from' do
5
+ class MyPromotionAction < Spree::PromotionAction
6
+ def perform(options = {})
7
+ order = options[:order]
8
+ order.adjustments.create!(amount: 1, order: order, source: self, label: 'foo')
9
+ true
10
+ end
11
+ end
12
+
13
+ let(:action) { promotion.actions.first! }
14
+ let!(:promotion) { create(:promotion, promotion_actions: [MyPromotionAction.new]) }
15
+ let(:order) { create(:order) }
16
+
17
+ # this adjustment should not get removed
18
+ let!(:other_adjustment) { create(:adjustment, order: order, source: nil) }
19
+
20
+ before do
21
+ action.perform(order: order)
22
+ @action_adjustment = order.adjustments.where(source: action).first!
23
+ end
24
+
25
+ it 'removes the action adjustment' do
26
+ expect(order.adjustments).to match_array([other_adjustment, @action_adjustment])
27
+
28
+ expect(Spree::Deprecation).to(
29
+ receive(:warn).
30
+ with(/"MyPromotionAction" does not define #remove_from/, anything)
31
+ )
32
+
33
+ action.remove_from(order)
34
+
35
+ expect(order.adjustments).to eq([other_adjustment])
36
+ end
37
+ end
38
+ end
@@ -252,57 +252,59 @@ module Spree
252
252
 
253
253
  context "for an order with taxable line items" do
254
254
  let(:store) { create(:store) }
255
+ let(:order) { create(:order, store: store) }
256
+ let(:tax_category) { create(:tax_category, name: "Taxable Foo") }
257
+ let(:zone) { create(:zone, :with_country) }
258
+ let!(:tax_rate) { create(:tax_rate, amount: 0.1, tax_category: tax_category, zone: zone )}
259
+
255
260
  before(:each) do
256
- @country = create(:country)
257
- @zone = create(:zone, name: "Country Zone", default_tax: true, zone_members: [])
258
- @zone.zone_members.create(zoneable: @country)
259
- @category = Spree::TaxCategory.create name: "Taxable Foo"
260
- @rate1 = Spree::TaxRate.create(
261
- amount: 0.10,
262
- calculator: Spree::Calculator::DefaultTax.create,
263
- tax_category: @category,
264
- zone: @zone
265
- )
266
-
267
- @order = Spree::Order.create!(store: store)
268
- allow(@order).to receive_messages coupon_code: "10off"
261
+ expect(order).to receive(:tax_address).at_least(:once).and_return(Spree::Tax::TaxLocation.new(country: zone.countries.first))
269
262
  end
263
+
270
264
  context "and the product price is less than promo discount" do
271
265
  before(:each) do
266
+ expect(order).to receive(:coupon_code).at_least(:once).and_return("10off")
267
+
272
268
  3.times do |_i|
273
- taxable = create(:product, tax_category: @category, price: 9.0)
274
- @order.contents.add(taxable.master, 1)
269
+ taxable = create(:product, tax_category: tax_category, price: 9.0)
270
+ order.contents.add(taxable.master, 1)
275
271
  end
276
272
  end
273
+
277
274
  it "successfully applies the promo" do
278
275
  # 3 * (9 + 0.9)
279
- expect(@order.total).to eq(29.7)
280
- coupon = Coupon.new(@order)
276
+ expect(order.total).to eq(29.7)
277
+ coupon = Coupon.new(order)
281
278
  coupon.apply
282
279
  expect(coupon.success).to be_present
283
280
  # 3 * ((9 - [9,10].min) + 0)
284
- expect(@order.reload.total).to eq(0)
285
- expect(@order.additional_tax_total).to eq(0)
281
+ expect(order.reload.total).to eq(0)
282
+ expect(order.additional_tax_total).to eq(0)
286
283
  end
287
284
  end
285
+
288
286
  context "and the product price is greater than promo discount" do
289
287
  before(:each) do
288
+ expect(order).to receive(:coupon_code).at_least(:once).and_return("10off")
289
+
290
290
  3.times do |_i|
291
- taxable = create(:product, tax_category: @category, price: 11.0)
292
- @order.contents.add(taxable.master, 2)
291
+ taxable = create(:product, tax_category: tax_category, price: 11.0)
292
+ order.contents.add(taxable.master, 2)
293
293
  end
294
294
  end
295
+
295
296
  it "successfully applies the promo" do
296
297
  # 3 * (22 + 2.2)
297
- expect(@order.total.to_f).to eq(72.6)
298
- coupon = Coupon.new(@order)
298
+ expect(order.total.to_f).to eq(72.6)
299
+ coupon = Coupon.new(order)
299
300
  coupon.apply
300
301
  expect(coupon.success).to be_present
301
302
  # 3 * ( (22 - 10) + 1.2)
302
- expect(@order.reload.total).to eq(39.6)
303
- expect(@order.additional_tax_total).to eq(3.6)
303
+ expect(order.reload.total).to eq(39.6)
304
+ expect(order.additional_tax_total).to eq(3.6)
304
305
  end
305
306
  end
307
+
306
308
  context "and multiple quantity per line item" do
307
309
  before(:each) do
308
310
  twnty_off = create(:promotion, name: "promo", code: "20off")
@@ -310,22 +312,23 @@ module Spree
310
312
  Promotion::Actions::CreateItemAdjustments.create(promotion: twnty_off,
311
313
  calculator: twnty_off_calc)
312
314
 
313
- allow(@order).to receive(:coupon_code).and_call_original
314
- allow(@order).to receive_messages coupon_code: "20off"
315
+ expect(order).to receive(:coupon_code).at_least(:once).and_return("20off")
316
+
315
317
  3.times do |_i|
316
- taxable = create(:product, tax_category: @category, price: 10.0)
317
- @order.contents.add(taxable.master, 2)
318
+ taxable = create(:product, tax_category: tax_category, price: 10.0)
319
+ order.contents.add(taxable.master, 2)
318
320
  end
319
321
  end
322
+
320
323
  it "successfully applies the promo" do
321
324
  # 3 * ((2 * 10) + 2.0)
322
- expect(@order.total.to_f).to eq(66)
323
- coupon = Coupon.new(@order)
325
+ expect(order.total.to_f).to eq(66)
326
+ coupon = Coupon.new(order)
324
327
  coupon.apply
325
328
  expect(coupon.success).to be_present
326
329
  # 0
327
- expect(@order.reload.total).to eq(0)
328
- expect(@order.additional_tax_total).to eq(0)
330
+ expect(order.reload.total).to eq(0)
331
+ expect(order.additional_tax_total).to eq(0)
329
332
  end
330
333
  end
331
334
  end
@@ -6,40 +6,39 @@ module Spree
6
6
  let(:order) { create(:order) }
7
7
  let(:shipment) { create(:shipment, order: order ) }
8
8
 
9
- let(:promotion) { Promotion.create!(name: "Free Shipping") }
10
- let(:calculator) { Calculator::FlatPercentItemTotal.new(preferred_flat_percent: 10) }
11
- let!(:action) { Promotion::Actions::FreeShipping.create(promotion: promotion) }
9
+ let(:action) { Spree::Promotion::Actions::FreeShipping.new }
12
10
 
13
11
  subject { Spree::PromotionHandler::FreeShipping.new(order) }
14
12
 
15
- context "activates in Shipment level" do
13
+ context 'with apply_automatically' do
14
+ let!(:promotion) { create(:promotion, apply_automatically: true, promotion_actions: [action]) }
15
+
16
16
  it "creates the adjustment" do
17
17
  expect { subject.activate }.to change { shipment.adjustments.count }.by(1)
18
18
  end
19
19
  end
20
20
 
21
- context "if promo has a code" do
22
- let!(:promotion_code) { create(:promotion_code, promotion: promotion) }
23
-
24
- it "does adjust the shipment when applied to order" do
25
- pending "broken by 2-2-dev merge"
26
- order.order_promotions.create!(promotion: promotion, promotion_code: promotion_code)
27
-
28
- expect { subject.activate }.to change { shipment.adjustments.count }
29
- end
21
+ context 'with a code' do
22
+ let!(:promotion) { create(:promotion, code: 'freeshipping', promotion_actions: [action]) }
30
23
 
31
- it "does not adjust the shipment when not applied to order" do
32
- expect { subject.activate }.to_not change { shipment.adjustments.count }
33
- end
34
- end
24
+ context 'when already applied' do
25
+ before do
26
+ order.order_promotions.create!(promotion: promotion, promotion_code: promotion.codes.first)
27
+ end
35
28
 
36
- context "if promo has a path" do
37
- before do
38
- promotion.update_column(:path, "path")
29
+ it 'adjusts the shipment' do
30
+ expect {
31
+ subject.activate
32
+ }.to change { shipment.adjustments.count }
33
+ end
39
34
  end
40
35
 
41
- it "does not adjust the shipment" do
42
- expect { subject.activate }.to_not change { shipment.adjustments.count }
36
+ context 'when not already applied' do
37
+ it 'does not adjust the shipment' do
38
+ expect {
39
+ subject.activate
40
+ }.to_not change { shipment.adjustments.count }
41
+ end
43
42
  end
44
43
  end
45
44
  end
@@ -142,6 +142,30 @@ describe Spree::Promotion, type: :model do
142
142
  expect(promotion.activate(@payload)).to be true
143
143
  expect(promotion.orders.first).to eql @order
144
144
  end
145
+
146
+ it 'keeps in-memory associations updated' do
147
+ # load all the relevant associations into memory
148
+ promotion.order_promotions.to_a
149
+ promotion.orders.to_a
150
+ @order.order_promotions.to_a
151
+ @order.promotions.to_a
152
+
153
+ expect(promotion.order_promotions.size).to eq(0)
154
+ expect(promotion.orders.size).to eq(0)
155
+ expect(@order.order_promotions.size).to eq(0)
156
+ expect(@order.promotions.size).to eq(0)
157
+
158
+ expect(
159
+ promotion.activate(@payload)
160
+ ).to eq(true)
161
+
162
+ aggregate_failures do
163
+ expect(promotion.order_promotions.size).to eq(1)
164
+ expect(promotion.orders.size).to eq(1)
165
+ expect(@order.order_promotions.size).to eq(1)
166
+ expect(@order.promotions.size).to eq(1)
167
+ end
168
+ end
145
169
  end
146
170
  context "when not activated" do
147
171
  it "will not assign the order" do
@@ -176,6 +200,25 @@ describe Spree::Promotion, type: :model do
176
200
  end
177
201
  end
178
202
 
203
+ describe '#remove_from' do
204
+ let(:promotion) { create(:promotion, :with_line_item_adjustment) }
205
+ let(:order) { create(:order_with_line_items) }
206
+
207
+ before do
208
+ promotion.activate(order: order)
209
+ end
210
+
211
+ it 'removes the promotion' do
212
+ expect(order.promotions).to include(promotion)
213
+ expect(order.line_items.flat_map(&:adjustments)).to be_present
214
+
215
+ promotion.remove_from(order)
216
+
217
+ expect(order.promotions).to be_empty
218
+ expect(order.line_items.flat_map(&:adjustments)).to be_empty
219
+ end
220
+ end
221
+
179
222
  describe "#usage_limit_exceeded?" do
180
223
  subject { promotion.usage_limit_exceeded? }
181
224
 
@@ -554,8 +597,7 @@ describe Spree::Promotion, type: :model do
554
597
  allow(rule2).to receive_messages(eligible?: true, applicable?: true)
555
598
 
556
599
  promotion.promotion_rules = [rule1, rule2]
557
- allow(promotion).to receive_message_chain(:rules, :none?).and_return(false)
558
- allow(promotion).to receive_message_chain(:rules, :for).and_return(promotion.promotion_rules)
600
+ allow(promotion.promotion_rules).to receive(:for).and_return(promotion.promotion_rules)
559
601
  end
560
602
  it "returns the eligible rules" do
561
603
  expect(promotion.eligible_rules(promotable)).to eq [rule1, rule2]
@@ -573,8 +615,7 @@ describe Spree::Promotion, type: :model do
573
615
  allow(rule2).to receive_messages(eligible?: false, applicable?: true, eligibility_errors: errors)
574
616
 
575
617
  promotion.promotion_rules = [rule1, rule2]
576
- allow(promotion).to receive_message_chain(:rules, :none?).and_return(false)
577
- allow(promotion).to receive_message_chain(:rules, :for).and_return(promotion.promotion_rules)
618
+ allow(promotion.promotion_rules).to receive(:for).and_return(promotion.promotion_rules)
578
619
  end
579
620
  it "returns nil" do
580
621
  expect(promotion.eligible_rules(promotable)).to be_nil
@@ -606,8 +647,7 @@ describe Spree::Promotion, type: :model do
606
647
  allow(rule).to receive_messages(eligible?: false, applicable?: true, eligibility_errors: errors)
607
648
 
608
649
  promotion.promotion_rules = [rule]
609
- allow(promotion).to receive_message_chain(:rules, :for).and_return(promotion.promotion_rules)
610
- allow(promotion).to receive_message_chain(:rules, :none?).and_return(false)
650
+ allow(promotion.promotion_rules).to receive(:for).and_return(promotion.promotion_rules)
611
651
  end
612
652
  it "returns nil" do
613
653
  expect(promotion.eligible_rules(promotable)).to be_nil