solidus_core 2.7.4 → 2.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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