solidus_core 2.7.4 → 2.8.0

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 (136) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +19 -17
  3. data/app/assets/images/logo/solidus.svg +18 -0
  4. data/app/assets/javascripts/spree.js.erb +2 -2
  5. data/app/helpers/spree/base_helper.rb +1 -7
  6. data/app/helpers/spree/taxons_helper.rb +2 -2
  7. data/app/mailers/spree/carton_mailer.rb +4 -4
  8. data/app/models/spree/calculator/flat_percent_item_total.rb +4 -1
  9. data/app/models/spree/calculator/shipping/flat_percent_item_total.rb +5 -3
  10. data/app/models/spree/calculator/tiered_percent.rb +2 -1
  11. data/app/models/spree/country.rb +8 -0
  12. data/app/models/spree/fulfilment_changer.rb +9 -1
  13. data/app/models/spree/gallery/product_gallery.rb +18 -0
  14. data/app/models/spree/gallery/variant_gallery.rb +21 -0
  15. data/app/models/spree/image.rb +11 -1
  16. data/app/models/spree/inventory_unit.rb +8 -0
  17. data/app/models/spree/line_item.rb +1 -1
  18. data/app/models/spree/order.rb +0 -4
  19. data/app/models/spree/order_cancellations.rb +31 -10
  20. data/app/models/spree/order_contents.rb +1 -5
  21. data/app/models/spree/order_inventory.rb +5 -4
  22. data/app/models/spree/product.rb +9 -0
  23. data/app/models/spree/product/scopes.rb +3 -4
  24. data/app/models/spree/promotion.rb +1 -6
  25. data/app/models/spree/promotion_handler/coupon.rb +15 -0
  26. data/app/models/spree/reimbursement.rb +21 -6
  27. data/app/models/spree/reimbursement_performer.rb +12 -6
  28. data/app/models/spree/reimbursement_type.rb +1 -1
  29. data/app/models/spree/reimbursement_type/credit.rb +5 -2
  30. data/app/models/spree/reimbursement_type/exchange.rb +1 -1
  31. data/app/models/spree/reimbursement_type/original_payment.rb +1 -1
  32. data/app/models/spree/reimbursement_type/reimbursement_helpers.rb +6 -6
  33. data/app/models/spree/reimbursement_type/store_credit.rb +18 -3
  34. data/app/models/spree/shipment.rb +11 -11
  35. data/app/models/spree/stock/allocator/base.rb +19 -0
  36. data/app/models/spree/stock/allocator/on_hand_first.rb +42 -0
  37. data/app/models/spree/stock/content_item.rb +1 -1
  38. data/app/models/spree/stock/inventory_units_finalizer.rb +47 -0
  39. data/app/models/spree/stock/location_sorter/base.rb +38 -0
  40. data/app/models/spree/stock/location_sorter/default_first.rb +15 -0
  41. data/app/models/spree/stock/location_sorter/unsorted.rb +14 -0
  42. data/app/models/spree/stock/simple_coordinator.rb +24 -10
  43. data/app/models/spree/stock_location.rb +2 -0
  44. data/app/models/spree/store_credit.rb +4 -12
  45. data/app/models/spree/store_credit_event.rb +2 -2
  46. data/app/models/spree/store_credit_reason.rb +11 -0
  47. data/app/models/spree/taxon.rb +8 -3
  48. data/app/models/spree/unit_cancel.rb +3 -0
  49. data/app/models/spree/variant.rb +18 -7
  50. data/config/initializers/money.rb +5 -0
  51. data/config/locales/en.yml +661 -527
  52. data/db/default/spree/store_credit.rb +1 -1
  53. data/db/default/spree/zones.rb +2 -2
  54. data/db/migrate/20180710170104_create_spree_store_credit_reasons_table.rb +42 -0
  55. data/db/migrate/20190106184413_remove_code_from_spree_promotions.rb +41 -0
  56. data/lib/generators/spree/dummy/templates/rails/test.rb +0 -3
  57. data/lib/generators/spree/install/install_generator.rb +2 -2
  58. data/lib/generators/spree/install/templates/config/initializers/spree.rb.tt +2 -2
  59. data/lib/generators/spree/install/templates/vendor/assets/javascripts/spree/backend/all.js +1 -1
  60. data/lib/generators/spree/install/templates/vendor/assets/javascripts/spree/frontend/all.js +1 -1
  61. data/lib/solidus/migrations/promotions_with_code_handlers.rb +66 -0
  62. data/lib/spree/app_configuration.rb +20 -4
  63. data/lib/spree/core/controller_helpers/common.rb +1 -1
  64. data/lib/spree/core/stock_configuration.rb +12 -0
  65. data/lib/spree/core/version.rb +1 -1
  66. data/lib/spree/i18n.rb +4 -0
  67. data/lib/spree/money.rb +13 -11
  68. data/lib/spree/permission_sets.rb +0 -1
  69. data/lib/spree/permission_sets/promotion_management.rb +1 -0
  70. data/lib/spree/testing_support/dummy_app.rb +13 -2
  71. data/lib/spree/testing_support/dummy_app/assets/javascripts/spree/backend/all.js +1 -1
  72. data/lib/spree/testing_support/dummy_app/assets/javascripts/spree/frontend/all.js +1 -1
  73. data/lib/spree/testing_support/factories/store_credit_event_factory.rb +5 -5
  74. data/lib/spree/testing_support/factories/{store_credit_update_reason_factory.rb → store_credit_reason_factory.rb} +1 -1
  75. data/lib/spree/testing_support/partial_double_verification.rb +13 -0
  76. data/lib/spree/testing_support/shared_examples/gallery.rb +18 -0
  77. data/spec/helpers/products_helper_spec.rb +10 -8
  78. data/spec/helpers/taxons_helper_spec.rb +3 -1
  79. data/spec/lib/i18n_spec.rb +5 -0
  80. data/spec/lib/spree/core/controller_helpers/auth_spec.rb +6 -2
  81. data/spec/lib/spree/core/stock_configuration_spec.rb +19 -0
  82. data/spec/lib/spree/core/testing_support/factories/store_credit_reason_factory_spec.rb +14 -0
  83. data/spec/lib/spree/money_spec.rb +12 -13
  84. data/spec/migrate/20190106184413_remove_code_from_spree_promotions_spec.rb +136 -0
  85. data/spec/models/spree/calculator/flat_percent_item_total_spec.rb +10 -1
  86. data/spec/models/spree/calculator/shipping/flat_percent_item_total_spec.rb +18 -6
  87. data/spec/models/spree/calculator/tiered_percent_spec.rb +7 -1
  88. data/spec/models/spree/country_spec.rb +76 -0
  89. data/spec/models/spree/customer_return_spec.rb +2 -1
  90. data/spec/models/spree/fulfilment_changer_spec.rb +33 -0
  91. data/spec/models/spree/gallery/product_gallery_spec.rb +21 -0
  92. data/spec/models/spree/gallery/variant_gallery_spec.rb +21 -0
  93. data/spec/models/spree/inventory_unit_spec.rb +1 -4
  94. data/spec/models/spree/order/checkout_spec.rb +6 -6
  95. data/spec/models/spree/order/finalizing_spec.rb +1 -20
  96. data/spec/models/spree/order/outstanding_balance_integration_spec.rb +2 -1
  97. data/spec/models/spree/order/updating_spec.rb +1 -1
  98. data/spec/models/spree/order_cancellations_spec.rb +55 -14
  99. data/spec/models/spree/order_inventory_spec.rb +12 -5
  100. data/spec/models/spree/order_merger_spec.rb +6 -3
  101. data/spec/models/spree/order_spec.rb +3 -7
  102. data/spec/models/spree/order_updater_spec.rb +3 -8
  103. data/spec/models/spree/payment/cancellation_spec.rb +4 -3
  104. data/spec/models/spree/payment_spec.rb +1 -17
  105. data/spec/models/spree/permission_sets/promotion_management_spec.rb +2 -0
  106. data/spec/models/spree/product_spec.rb +10 -1
  107. data/spec/models/spree/promotion_handler/coupon_spec.rb +62 -8
  108. data/spec/models/spree/promotion_spec.rb +24 -10
  109. data/spec/models/spree/refund_spec.rb +2 -1
  110. data/spec/models/spree/reimbursement_performer_spec.rb +5 -4
  111. data/spec/models/spree/reimbursement_spec.rb +26 -2
  112. data/spec/models/spree/reimbursement_type/credit_spec.rb +2 -1
  113. data/spec/models/spree/reimbursement_type/exchange_spec.rb +2 -1
  114. data/spec/models/spree/reimbursement_type/original_payment_spec.rb +2 -1
  115. data/spec/models/spree/reimbursement_type/store_credit_spec.rb +14 -2
  116. data/spec/models/spree/return_item_spec.rb +1 -1
  117. data/spec/models/spree/shipment_spec.rb +20 -13
  118. data/spec/models/spree/shipping_calculator_spec.rb +13 -3
  119. data/spec/models/spree/stock/allocator/on_hand_first_spec.rb +146 -0
  120. data/spec/models/spree/stock/content_item_spec.rb +70 -0
  121. data/spec/models/spree/stock/estimator_spec.rb +5 -2
  122. data/spec/models/spree/stock/inventory_units_finalizer_spec.rb +34 -0
  123. data/spec/models/spree/stock/location_sorter/default_first_spec.rb +20 -0
  124. data/spec/models/spree/stock/location_sorter/unsorted_spec.rb +19 -0
  125. data/spec/models/spree/stock/simple_coordinator_spec.rb +17 -0
  126. data/spec/models/spree/store_credit_event_spec.rb +12 -12
  127. data/spec/models/spree/store_credit_spec.rb +2 -2
  128. data/spec/models/spree/unit_cancel_spec.rb +20 -1
  129. data/spec/models/spree/variant_spec.rb +46 -24
  130. data/spec/spec_helper.rb +1 -0
  131. metadata +30 -9
  132. data/.yardopts +0 -1
  133. data/app/models/spree/store_credit_update_reason.rb +0 -4
  134. data/lib/spree/permission_sets/report_display.rb +0 -11
  135. data/spec/lib/spree/core/testing_support/factories/store_credit_update_reason_factory_spec.rb +0 -14
  136. data/spec/models/spree/permission_sets/report_display_spec.rb +0 -25
@@ -5,7 +5,7 @@ require 'shared_examples/calculator_shared_examples'
5
5
 
6
6
  RSpec.describe Spree::Calculator::FlatPercentItemTotal, type: :model do
7
7
  let(:calculator) { Spree::Calculator::FlatPercentItemTotal.new }
8
- let(:line_item) { mock_model Spree::LineItem }
8
+ let(:line_item) { create(:line_item) }
9
9
 
10
10
  it_behaves_like 'a calculator with a description'
11
11
 
@@ -20,6 +20,15 @@ RSpec.describe Spree::Calculator::FlatPercentItemTotal, type: :model do
20
20
  expect(calculator.compute(line_item)).to eq 3.10
21
21
  end
22
22
 
23
+ it "should round result based on order currency" do
24
+ line_item.order.currency = 'JPY'
25
+ allow(line_item).to receive_messages amount: 31.08
26
+ expect(calculator.compute(line_item)).to eq 3
27
+
28
+ allow(line_item).to receive_messages amount: 31.00
29
+ expect(calculator.compute(line_item)).to eq 3
30
+ end
31
+
23
32
  it 'returns object.amount if computed amount is greater' do
24
33
  allow(calculator).to receive_messages preferred_flat_percent: 110
25
34
  allow(line_item).to receive_messages amount: 30.00
@@ -6,16 +6,23 @@ require 'shared_examples/calculator_shared_examples'
6
6
  module Spree
7
7
  module Calculator::Shipping
8
8
  RSpec.describe FlatPercentItemTotal, type: :model do
9
- let(:variant1) { build(:variant, price: 10.11) }
10
- let(:variant2) { build(:variant, price: 20.2222) }
11
-
12
9
  it_behaves_like 'a calculator with a description'
13
10
 
14
- let(:line_item1) { build(:line_item, variant: variant1) }
15
- let(:line_item2) { build(:line_item, variant: variant2) }
11
+ let(:line_item1) { build(:line_item, price: 10.11) }
12
+ let(:line_item2) { build(:line_item, price: 20.2222) }
13
+
14
+ let(:inventory_unit1) { build(:inventory_unit, line_item: line_item1) }
15
+ let(:inventory_unit2) { build(:inventory_unit, line_item: line_item2) }
16
16
 
17
17
  let(:package) do
18
- build(:stock_package, variants_contents: { variant1 => 2, variant2 => 1 })
18
+ build(
19
+ :stock_package,
20
+ contents: [
21
+ Spree::Stock::ContentItem.new(inventory_unit1),
22
+ Spree::Stock::ContentItem.new(inventory_unit1),
23
+ Spree::Stock::ContentItem.new(inventory_unit2),
24
+ ]
25
+ )
19
26
  end
20
27
 
21
28
  subject { FlatPercentItemTotal.new(preferred_flat_percent: 10) }
@@ -24,6 +31,11 @@ module Spree
24
31
  expect(subject.compute(package)).to eq(4.04)
25
32
  end
26
33
 
34
+ it "should round result based on order currency" do
35
+ package.order.currency = 'JPY'
36
+ expect(subject.compute(package)).to eq(4)
37
+ end
38
+
27
39
  it "should return a bigdecimal" do
28
40
  expect(subject.compute(package)).to be_a(BigDecimal)
29
41
  end
@@ -135,9 +135,15 @@ RSpec.describe Spree::Calculator::TieredPercent, type: :model do
135
135
  end
136
136
 
137
137
  context "when the order's currency does not match the calculator" do
138
- let(:preferred_currency) { "CAD" }
138
+ let(:preferred_currency) { "JPY" }
139
139
  let(:line_item_count) { 1 }
140
+ let(:price) { 15 }
140
141
  it { is_expected.to eq 0 }
142
+
143
+ it "rounds based on currency" do
144
+ allow(order).to receive_messages currency: "JPY"
145
+ expect(subject).to eq(2)
146
+ end
141
147
  end
142
148
  end
143
149
 
@@ -60,6 +60,82 @@ RSpec.describe Spree::Country, type: :model do
60
60
  end
61
61
  end
62
62
 
63
+ describe '.available' do
64
+ let!(:united_states) { create(:country, iso: 'US') }
65
+ let!(:canada) { create(:country, iso: 'CA') }
66
+ let!(:italy) { create(:country, iso: 'IT') }
67
+ let!(:custom_zone) { create(:zone, name: 'Custom Zone', countries: [united_states, italy]) }
68
+
69
+ context 'with a checkout zone defined' do
70
+ context 'when checkout zone is of type country' do
71
+ let!(:checkout_zone) { create(:zone, name: 'Checkout Zone', countries: [united_states, canada]) }
72
+
73
+ before do
74
+ Spree::Config.checkout_zone = checkout_zone.name
75
+ end
76
+
77
+ context 'with no arguments' do
78
+ it 'returns "Checkout Zone" countries' do
79
+ expect(described_class.available).to contain_exactly(united_states, canada)
80
+ end
81
+ end
82
+
83
+ context 'setting nil as restricting zone' do
84
+ it 'returns all countries' do
85
+ expect(described_class.available(restrict_to_zone: nil)).to contain_exactly(united_states, canada, italy)
86
+ end
87
+ end
88
+
89
+ context 'setting "Custom Zone" as restricting zone' do
90
+ it 'returns "Custom Zone" countries' do
91
+ expect(described_class.available(restrict_to_zone: 'Custom Zone')).to contain_exactly(united_states, italy)
92
+ end
93
+ end
94
+
95
+ context 'setting "Checkout Zone" as restricting zone' do
96
+ it 'returns "Checkout Zone" countries' do
97
+ expect(described_class.available(restrict_to_zone: 'Checkout Zone')).to contain_exactly(united_states, canada)
98
+ end
99
+ end
100
+ end
101
+
102
+ context 'when checkout zone is of type state' do
103
+ let!(:state) { create(:state, country: united_states) }
104
+ let!(:checkout_zone) { create(:zone, name: 'Checkout Zone', states: [state]) }
105
+
106
+ before do
107
+ Spree::Config[:checkout_zone] = checkout_zone.name
108
+ end
109
+
110
+ context 'with no arguments' do
111
+ it 'returns all countries' do
112
+ expect(described_class.available(restrict_to_zone: nil)).to contain_exactly(united_states, canada, italy)
113
+ end
114
+ end
115
+ end
116
+ end
117
+
118
+ context 'with no checkout zone defined' do
119
+ context 'with no arguments' do
120
+ it 'returns all countries' do
121
+ expect(described_class.available).to contain_exactly(united_states, canada, italy)
122
+ end
123
+ end
124
+
125
+ context 'setting nil as restricting zone' do
126
+ it 'returns all countries' do
127
+ expect(described_class.available(restrict_to_zone: nil)).to contain_exactly(united_states, canada, italy)
128
+ end
129
+ end
130
+
131
+ context 'setting "Custom Zone" as restricting zone' do
132
+ it 'returns "Custom Zone" countries' do
133
+ expect(described_class.available(restrict_to_zone: 'Custom Zone')).to contain_exactly(united_states, italy)
134
+ end
135
+ end
136
+ end
137
+ end
138
+
63
139
  describe '#prices' do
64
140
  let(:country) { create(:country) }
65
141
  subject { country.prices }
@@ -282,7 +282,8 @@ RSpec.describe Spree::CustomerReturn, type: :model do
282
282
  end
283
283
 
284
284
  context 'when all reimbursements are reimbursed' do
285
- before { reimbursement.perform! }
285
+ let(:created_by_user) { create(:user, email: 'user@email.com') }
286
+ before { reimbursement.perform!(created_by: created_by_user) }
286
287
 
287
288
  it { is_expected.to be true }
288
289
  end
@@ -37,6 +37,39 @@ RSpec.describe Spree::FulfilmentChanger do
37
37
  variant.stock_items.first.update_column(:count_on_hand, 100)
38
38
  end
39
39
 
40
+ context "when the current shipment stock location is the same of the target shipment" do
41
+ let(:current_shipment_inventory_unit_count) { 1 }
42
+ let(:quantity) { current_shipment_inventory_unit_count }
43
+
44
+ context "when the stock location is empty" do
45
+ before do
46
+ variant.stock_items.first.update_column(:count_on_hand, 0)
47
+ end
48
+
49
+ context "when the inventory unit is backordered" do
50
+ before do
51
+ current_shipment.inventory_units.first.update state: :backordered
52
+ end
53
+
54
+ it "creates a new backordered inventory unit" do
55
+ subject
56
+ expect(desired_shipment.inventory_units.first).to be_backordered
57
+ end
58
+ end
59
+
60
+ context "when the inventory unit is on hand" do
61
+ before do
62
+ current_shipment.inventory_units.first.update state: :on_hand
63
+ end
64
+
65
+ it "creates a new on hand inventory unit" do
66
+ subject
67
+ expect(desired_shipment.inventory_units.first).to be_on_hand
68
+ end
69
+ end
70
+ end
71
+ end
72
+
40
73
  context "when the current shipment has enough inventory units" do
41
74
  let(:current_shipment_inventory_unit_count) { 2 }
42
75
  let(:quantity) { 1 }
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+ require 'spree/testing_support/shared_examples/gallery'
5
+
6
+ RSpec.describe Spree::Gallery::ProductGallery do
7
+ let(:gallery) { described_class.new(product) }
8
+ let(:product) { create(:product) }
9
+
10
+ shared_context 'has multiple images' do
11
+ let(:first_image) { build(:image) }
12
+ let(:second_image) { build(:image) }
13
+
14
+ before do
15
+ product.images << first_image
16
+ product.images << second_image
17
+ end
18
+ end
19
+
20
+ it_behaves_like 'a gallery'
21
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+ require 'spree/testing_support/shared_examples/gallery'
5
+
6
+ RSpec.describe Spree::Gallery::VariantGallery do
7
+ let(:gallery) { described_class.new(variant) }
8
+ let(:variant) { build_stubbed(:variant) }
9
+
10
+ shared_context 'has multiple images' do
11
+ let(:first_image) { build(:image) }
12
+ let(:second_image) { build(:image) }
13
+
14
+ before do
15
+ variant.images << first_image
16
+ variant.images << second_image
17
+ end
18
+ end
19
+
20
+ it_behaves_like 'a gallery'
21
+ end
@@ -97,8 +97,6 @@ RSpec.describe Spree::InventoryUnit, type: :model do
97
97
  shipment.stock_location = stock_location
98
98
  shipment.shipping_methods << create(:shipping_method)
99
99
  shipment.order = other_order
100
- # We don't care about this in this test
101
- allow(shipment).to receive(:ensure_correct_adjustment)
102
100
  shipment.tap(&:save!)
103
101
  end
104
102
 
@@ -142,14 +140,13 @@ RSpec.describe Spree::InventoryUnit, type: :model do
142
140
  }
143
141
 
144
142
  it "should create a stock movement" do
143
+ expect(Spree::Deprecation).to receive(:warn)
145
144
  Spree::InventoryUnit.finalize_units!(inventory_units)
146
145
  expect(inventory_units.any?(&:pending)).to be false
147
146
  end
148
147
  end
149
148
 
150
149
  describe "#current_or_new_return_item" do
151
- before { allow(inventory_unit).to receive_messages(total_excluding_vat: 100.0) }
152
-
153
150
  subject { inventory_unit.current_or_new_return_item }
154
151
 
155
152
  context "associated with a return item" do
@@ -36,7 +36,7 @@ RSpec.describe Spree::Order, type: :model do
36
36
  Spree::Order.checkout_flow(&@old_checkout_flow)
37
37
  end
38
38
 
39
- it '.remove_transition' do
39
+ it '.remove_transition', partial_double_verification: false do
40
40
  options = { from: transitions.first.keys.first, to: transitions.first.values.first }
41
41
  allow(Spree::Order).to receive(:next_event_transition).and_return([options])
42
42
  expect(Spree::Order.remove_transition(options)).to be_truthy
@@ -238,7 +238,7 @@ RSpec.describe Spree::Order, type: :model do
238
238
  order.ship_address = ship_address
239
239
  end
240
240
 
241
- context 'when order has default selected_shipping_rate_id' do
241
+ context 'when order has default selected_shipping_rate_id', partial_double_verification: false do
242
242
  let(:shipment) { create(:shipment, order: order) }
243
243
  let(:shipping_method) { create(:shipping_method) }
244
244
  let(:shipping_rate) {
@@ -277,7 +277,7 @@ RSpec.describe Spree::Order, type: :model do
277
277
  end
278
278
  end
279
279
 
280
- context "from delivery" do
280
+ context "from delivery", partial_double_verification: false do
281
281
  let(:ship_address) { FactoryBot.create(:ship_address) }
282
282
 
283
283
  before do
@@ -537,7 +537,7 @@ RSpec.describe Spree::Order, type: :model do
537
537
  end
538
538
  end
539
539
 
540
- context "default credit card" do
540
+ context "default credit card", partial_double_verification: false do
541
541
  before do
542
542
  order.user = FactoryBot.create(:user)
543
543
  order.store = FactoryBot.create(:store)
@@ -568,7 +568,7 @@ RSpec.describe Spree::Order, type: :model do
568
568
  end
569
569
  end
570
570
 
571
- context "a payment fails during processing" do
571
+ context "a payment fails during processing", partial_double_verification: false do
572
572
  before do
573
573
  order.user = FactoryBot.create(:user)
574
574
  order.email = 'spree@example.org'
@@ -656,7 +656,7 @@ RSpec.describe Spree::Order, type: :model do
656
656
  assert_state_changed(order, 'cart', 'complete')
657
657
  end
658
658
 
659
- it "does not attempt to process payments" do
659
+ it "does not attempt to process payments", partial_double_verification: false do
660
660
  order.email = 'user@example.com'
661
661
  allow(order).to receive(:ensure_promotions_eligible).and_return(true)
662
662
  allow(order).to receive(:ensure_line_item_variants_are_not_deleted).and_return(true)
@@ -3,11 +3,8 @@
3
3
  require 'rails_helper'
4
4
 
5
5
  RSpec.describe Spree::Order, type: :model do
6
- let(:order) { stub_model("Spree::Order") }
7
-
8
6
  context "#finalize!" do
9
- let!(:store) { create(:store) }
10
- let(:order) { Spree::Order.create(email: 'test@example.com', store: store) }
7
+ let(:order) { create(:order_ready_to_complete) }
11
8
 
12
9
  before do
13
10
  order.update_column :state, 'complete'
@@ -26,29 +23,13 @@ RSpec.describe Spree::Order, type: :model do
26
23
  order.finalize!
27
24
  end
28
25
 
29
- it "should decrease the stock for each variant in the shipment" do
30
- order.shipments.each do |shipment|
31
- expect(shipment.stock_location).to receive(:decrease_stock_for_variant)
32
- end
33
- order.finalize!
34
- end
35
-
36
26
  it "should change the shipment state to ready if order is paid" do
37
- Spree::Shipment.create(order: order)
38
- order.shipments.reload
39
-
40
27
  allow(order).to receive_messages(paid?: true, complete?: true)
41
28
  order.finalize!
42
29
  order.reload # reload so we're sure the changes are persisted
43
30
  expect(order.shipment_state).to eq('ready')
44
31
  end
45
32
 
46
- it "should not sell inventory units if track_inventory_levels is false" do
47
- Spree::Config.set track_inventory_levels: false
48
- expect(Spree::InventoryUnit).not_to receive(:sell_units)
49
- order.finalize!
50
- end
51
-
52
33
  it "should send an order confirmation email" do
53
34
  mail_message = double "Mail::Message"
54
35
  expect(Spree::OrderMailer).to receive(:confirm_email).with(order).and_return mail_message
@@ -83,13 +83,14 @@ RSpec.describe "Outstanding balance integration tests" do
83
83
  context 'with a cancelled item' do
84
84
  let(:cancelations) { Spree::OrderCancellations.new(order) }
85
85
  let(:cancelled_item) { item_1 }
86
+ let(:created_by_user) { create(:user, email: 'user@email.com') }
86
87
 
87
88
  before do
88
89
  # Required to refund
89
90
  Spree::RefundReason.create!(name: Spree::RefundReason::RETURN_PROCESSING_REASON, mutable: false)
90
91
 
91
92
  cancelations.cancel_unit(cancelled_item.inventory_units.first)
92
- cancelations.reimburse_units(cancelled_item.inventory_units)
93
+ cancelations.reimburse_units(cancelled_item.inventory_units, created_by: created_by_user)
93
94
 
94
95
  order.reload
95
96
  end
@@ -6,7 +6,7 @@ RSpec.describe Spree::Order, type: :model do
6
6
  let(:order) { create(:order) }
7
7
 
8
8
  context "#update!" do
9
- context "when there are update hooks" do
9
+ context "when there are update hooks", partial_double_verification: false do
10
10
  before { Spree::Order.register_update_hook :foo }
11
11
  after { Spree::Order.update_hooks.clear }
12
12
  it "should call each of the update hooks" do
@@ -4,7 +4,7 @@ require 'rails_helper'
4
4
 
5
5
  RSpec.describe Spree::OrderCancellations do
6
6
  describe "#cancel_unit" do
7
- subject { Spree::OrderCancellations.new(order).cancel_unit(inventory_unit) }
7
+ subject { described_class.new(order).cancel_unit(inventory_unit) }
8
8
  let(:order) { create(:shipped_order, line_items_count: 1) }
9
9
  let(:inventory_unit) { order.inventory_units.first }
10
10
 
@@ -34,7 +34,8 @@ RSpec.describe Spree::OrderCancellations do
34
34
  context "when a whodunnit is specified" do
35
35
  subject { order.cancellations.cancel_unit(inventory_unit, whodunnit: "some automated system") }
36
36
 
37
- it "sets the user on the UnitCancel" do
37
+ it "sets the user on the UnitCancel and print a deprecation" do
38
+ expect(Spree::Deprecation).to receive(:warn)
38
39
  expect(subject.created_by).to eq("some automated system")
39
40
  end
40
41
  end
@@ -44,13 +45,28 @@ RSpec.describe Spree::OrderCancellations do
44
45
  expect(subject.created_by).to be_nil
45
46
  end
46
47
  end
48
+
49
+ context "when a created_by is specified" do
50
+ subject { order.cancellations.cancel_unit(inventory_unit, created_by: "some automated system") }
51
+
52
+ it "sets the user on the UnitCancel" do
53
+ expect(subject.created_by).to eq("some automated system")
54
+ end
55
+ end
56
+
57
+ context "when a created_by is not specified" do
58
+ it "does not set created_by on the UnitCancel" do
59
+ expect(subject.created_by).to be_nil
60
+ end
61
+ end
47
62
  end
48
63
 
49
64
  describe "#reimburse_units" do
50
- subject { Spree::OrderCancellations.new(order).reimburse_units(inventory_units) }
65
+ subject { described_class.new(order).reimburse_units(inventory_units, created_by: created_by_user) }
51
66
  let(:order) { create(:shipped_order, line_items_count: 2) }
52
67
  let(:inventory_units) { order.inventory_units }
53
68
  let!(:default_refund_reason) { Spree::RefundReason.find_or_create_by!(name: Spree::RefundReason::RETURN_PROCESSING_REASON, mutable: false) }
69
+ let(:created_by_user) { create(:user, email: 'user@email.com') }
54
70
 
55
71
  it "creates and performs a reimbursement" do
56
72
  expect { subject }.to change { Spree::Reimbursement.count }.by(1)
@@ -67,7 +83,7 @@ RSpec.describe Spree::OrderCancellations do
67
83
  end
68
84
 
69
85
  describe "#short_ship" do
70
- subject { Spree::OrderCancellations.new(order).short_ship([inventory_unit]) }
86
+ subject { described_class.new(order).short_ship([inventory_unit]) }
71
87
 
72
88
  let(:order) { create(:order_ready_to_ship, line_items_count: 1) }
73
89
  let(:inventory_unit) { order.inventory_units.first }
@@ -94,7 +110,19 @@ RSpec.describe Spree::OrderCancellations do
94
110
  end
95
111
 
96
112
  it "adjusts the order" do
97
- expect { subject }.to change { order.total }.by(-10.0)
113
+ expect { subject }.to change { order.reload.total }.by(-10.0)
114
+ end
115
+
116
+ context "multiple inventory units" do
117
+ subject { described_class.new(order).short_ship(inventory_units) }
118
+
119
+ let(:quantity) { 4 }
120
+ let!(:order) { create(:order_with_line_items, line_items_attributes: [{ quantity: quantity }]) }
121
+ let(:inventory_units) { Spree::InventoryUnit.find(order.line_items.first.inventory_units.pluck(:id)) }
122
+
123
+ it "adjusts the order" do
124
+ expect { subject }.to change { order.reload.total }.by(-40.0)
125
+ end
98
126
  end
99
127
 
100
128
  it "sends a cancellation email" do
@@ -105,14 +133,14 @@ RSpec.describe Spree::OrderCancellations do
105
133
  end
106
134
 
107
135
  context "when send_cancellation_mailer is false" do
108
- subject { Spree::OrderCancellations.new(order).short_ship([inventory_unit]) }
136
+ subject { described_class.new(order).short_ship([inventory_unit]) }
109
137
 
110
138
  before do
111
- @original_send_boolean = Spree::OrderCancellations.send_cancellation_mailer
112
- Spree::OrderCancellations.send_cancellation_mailer = false
139
+ @original_send_boolean = described_class.send_cancellation_mailer
140
+ described_class.send_cancellation_mailer = false
113
141
  end
114
142
 
115
- after { Spree::OrderCancellations.send_cancellation_mailer = @original_send_boolean }
143
+ after { described_class.send_cancellation_mailer = @original_send_boolean }
116
144
 
117
145
  it "does not send a cancellation email" do
118
146
  expect(Spree::OrderMailer).not_to receive(:inventory_cancellation_email)
@@ -120,8 +148,8 @@ RSpec.describe Spree::OrderCancellations do
120
148
  end
121
149
  end
122
150
 
123
- context "with a who" do
124
- subject { order.cancellations.short_ship([inventory_unit], whodunnit: 'some automated system') }
151
+ context "when a created_by is specified" do
152
+ subject { order.cancellations.short_ship([inventory_unit], created_by: 'some automated system') }
125
153
 
126
154
  let(:user) { order.user }
127
155
 
@@ -131,6 +159,19 @@ RSpec.describe Spree::OrderCancellations do
131
159
  end
132
160
  end
133
161
 
162
+ context "when a whodunnit is specified" do
163
+ subject { order.cancellations.short_ship([inventory_unit], whodunnit: 'some automated system') }
164
+
165
+ let(:user) { order.user }
166
+
167
+ it "sets the user on the UnitCancel and raises a deprecation # WARNING: " do
168
+ expect(Spree::Deprecation).to receive(:warn)
169
+
170
+ expect { subject }.to change { Spree::UnitCancel.count }.by(1)
171
+ expect(Spree::UnitCancel.last.created_by).to eq("some automated system")
172
+ end
173
+ end
174
+
134
175
  context "when rounding is required" do
135
176
  let(:order) { create(:order_ready_to_ship, line_items_count: 1, line_items_price: 0.83) }
136
177
  let(:line_item) { order.line_items.to_a.first }
@@ -172,11 +213,11 @@ RSpec.describe Spree::OrderCancellations do
172
213
  let(:short_ship_tax_notifier) { double }
173
214
 
174
215
  before do
175
- @old_notifier = Spree::OrderCancellations.short_ship_tax_notifier
176
- Spree::OrderCancellations.short_ship_tax_notifier = short_ship_tax_notifier
216
+ @old_notifier = described_class.short_ship_tax_notifier
217
+ described_class.short_ship_tax_notifier = short_ship_tax_notifier
177
218
  end
178
219
  after do
179
- Spree::OrderCancellations.short_ship_tax_notifier = @old_notifier
220
+ described_class.short_ship_tax_notifier = @old_notifier
180
221
  end
181
222
 
182
223
  it 'calls the short_ship_tax_notifier' do