solidus_core 1.1.0 → 1.1.1

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 (228) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +3 -0
  3. data/Rakefile +16 -0
  4. data/script/rails +9 -0
  5. data/solidus_core.gemspec +48 -0
  6. data/spec/fixtures/thinking-cat.jpg +0 -0
  7. data/spec/helpers/base_helper_spec.rb +173 -0
  8. data/spec/helpers/order_helper_spec.rb +12 -0
  9. data/spec/helpers/products_helper_spec.rb +208 -0
  10. data/spec/helpers/taxons_helper_spec.rb +17 -0
  11. data/spec/lib/calculated_adjustments_spec.rb +7 -0
  12. data/spec/lib/i18n_spec.rb +106 -0
  13. data/spec/lib/search/base_spec.rb +86 -0
  14. data/spec/lib/search/variant_spec.rb +112 -0
  15. data/spec/lib/spree/core/controller_helpers/auth_spec.rb +66 -0
  16. data/spec/lib/spree/core/controller_helpers/order_spec.rb +92 -0
  17. data/spec/lib/spree/core/controller_helpers/payment_parameters_spec.rb +80 -0
  18. data/spec/lib/spree/core/controller_helpers/search_spec.rb +17 -0
  19. data/spec/lib/spree/core/controller_helpers/store_spec.rb +16 -0
  20. data/spec/lib/spree/core/controller_helpers/strong_parameters_spec.rb +39 -0
  21. data/spec/lib/spree/core/current_store_spec.rb +36 -0
  22. data/spec/lib/spree/core/delegate_belongs_to_spec.rb +24 -0
  23. data/spec/lib/spree/core/importer/order_spec.rb +431 -0
  24. data/spec/lib/spree/core/role_configuration_spec.rb +156 -0
  25. data/spec/lib/spree/core/unreturned_item_charger_spec.rb +130 -0
  26. data/spec/lib/spree/core/validators/email_spec.rb +48 -0
  27. data/spec/lib/spree/localized_number_spec.rb +38 -0
  28. data/spec/lib/spree/migrations_spec.rb +36 -0
  29. data/spec/lib/spree/money_spec.rb +127 -0
  30. data/spec/lib/tasks/exchanges_spec.rb +231 -0
  31. data/spec/lib/tasks/migrations/copy_shipped_shipments_to_cartons_spec.rb +115 -0
  32. data/spec/lib/tasks/order_capturing_spec.rb +56 -0
  33. data/spec/mailers/carton_mailer_spec.rb +55 -0
  34. data/spec/mailers/order_mailer_spec.rb +135 -0
  35. data/spec/mailers/reimbursement_mailer_spec.rb +40 -0
  36. data/spec/mailers/test_mailer_spec.rb +15 -0
  37. data/spec/models/spree/ability_spec.rb +276 -0
  38. data/spec/models/spree/address_spec.rb +376 -0
  39. data/spec/models/spree/adjustment_reason_spec.rb +13 -0
  40. data/spec/models/spree/adjustment_spec.rb +169 -0
  41. data/spec/models/spree/app_configuration_spec.rb +24 -0
  42. data/spec/models/spree/asset_spec.rb +24 -0
  43. data/spec/models/spree/calculator/default_tax_spec.rb +127 -0
  44. data/spec/models/spree/calculator/flat_percent_item_total_spec.rb +25 -0
  45. data/spec/models/spree/calculator/flat_rate_spec.rb +47 -0
  46. data/spec/models/spree/calculator/flexi_rate_spec.rb +41 -0
  47. data/spec/models/spree/calculator/percent_on_line_item_spec.rb +15 -0
  48. data/spec/models/spree/calculator/price_sack_spec.rb +30 -0
  49. data/spec/models/spree/calculator/refunds/default_refund_amount_spec.rb +60 -0
  50. data/spec/models/spree/calculator/shipping/flat_percent_item_total_spec.rb +23 -0
  51. data/spec/models/spree/calculator/shipping/flat_rate_spec.rb +13 -0
  52. data/spec/models/spree/calculator/shipping/flexi_rate_spec.rb +52 -0
  53. data/spec/models/spree/calculator/shipping/per_item_spec.rb +20 -0
  54. data/spec/models/spree/calculator/shipping/price_sack_spec.rb +30 -0
  55. data/spec/models/spree/calculator/tiered_flat_rate_spec.rb +36 -0
  56. data/spec/models/spree/calculator/tiered_percent_spec.rb +47 -0
  57. data/spec/models/spree/calculator_spec.rb +36 -0
  58. data/spec/models/spree/carton_spec.rb +133 -0
  59. data/spec/models/spree/classification_spec.rb +93 -0
  60. data/spec/models/spree/concerns/display_money_spec.rb +43 -0
  61. data/spec/models/spree/concerns/ordered_property_value_list_spec.rb +25 -0
  62. data/spec/models/spree/concerns/user_address_book_spec.rb +332 -0
  63. data/spec/models/spree/concerns/user_methods_spec.rb +41 -0
  64. data/spec/models/spree/credit_card_spec.rb +341 -0
  65. data/spec/models/spree/customer_return_spec.rb +276 -0
  66. data/spec/models/spree/exchange_spec.rb +79 -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 +104 -0
  70. data/spec/models/spree/inventory_unit_spec.rb +307 -0
  71. data/spec/models/spree/item_adjustments_spec.rb +275 -0
  72. data/spec/models/spree/line_item_spec.rb +199 -0
  73. data/spec/models/spree/option_type_spec.rb +14 -0
  74. data/spec/models/spree/option_value_spec.rb +45 -0
  75. data/spec/models/spree/order/address_spec.rb +50 -0
  76. data/spec/models/spree/order/adjustments_spec.rb +27 -0
  77. data/spec/models/spree/order/callbacks_spec.rb +42 -0
  78. data/spec/models/spree/order/checkout_spec.rb +884 -0
  79. data/spec/models/spree/order/currency_updater_spec.rb +32 -0
  80. data/spec/models/spree/order/finalizing_spec.rb +110 -0
  81. data/spec/models/spree/order/payment_spec.rb +243 -0
  82. data/spec/models/spree/order/risk_assessment_spec.rb +68 -0
  83. data/spec/models/spree/order/state_machine_spec.rb +209 -0
  84. data/spec/models/spree/order/tax_spec.rb +84 -0
  85. data/spec/models/spree/order/totals_spec.rb +24 -0
  86. data/spec/models/spree/order/updating_spec.rb +18 -0
  87. data/spec/models/spree/order/validations_spec.rb +15 -0
  88. data/spec/models/spree/order_cancellations_spec.rb +120 -0
  89. data/spec/models/spree/order_capturing_spec.rb +150 -0
  90. data/spec/models/spree/order_contents_spec.rb +307 -0
  91. data/spec/models/spree/order_inventory_spec.rb +228 -0
  92. data/spec/models/spree/order_mutex_spec.rb +85 -0
  93. data/spec/models/spree/order_promotion_spec.rb +31 -0
  94. data/spec/models/spree/order_shipping_spec.rb +241 -0
  95. data/spec/models/spree/order_spec.rb +1482 -0
  96. data/spec/models/spree/order_stock_location_spec.rb +18 -0
  97. data/spec/models/spree/order_updater_spec.rb +283 -0
  98. data/spec/models/spree/payment_method/store_credit_spec.rb +294 -0
  99. data/spec/models/spree/payment_method_spec.rb +147 -0
  100. data/spec/models/spree/payment_spec.rb +1087 -0
  101. data/spec/models/spree/permission_sets/base_spec.rb +12 -0
  102. data/spec/models/spree/permission_sets/configuration_display.rb +82 -0
  103. data/spec/models/spree/permission_sets/configuration_management_spec.rb +50 -0
  104. data/spec/models/spree/permission_sets/dashboard_display_spec.rb +22 -0
  105. data/spec/models/spree/permission_sets/order_display_spec.rb +55 -0
  106. data/spec/models/spree/permission_sets/order_management_spec.rb +42 -0
  107. data/spec/models/spree/permission_sets/product_display_spec.rb +60 -0
  108. data/spec/models/spree/permission_sets/product_management_spec.rb +40 -0
  109. data/spec/models/spree/permission_sets/promotion_display_spec.rb +40 -0
  110. data/spec/models/spree/permission_sets/promotion_management_spec.rb +26 -0
  111. data/spec/models/spree/permission_sets/report_display_spec.rb +24 -0
  112. data/spec/models/spree/permission_sets/restricted_stock_display_spec.rb +41 -0
  113. data/spec/models/spree/permission_sets/restricted_stock_management_spec.rb +41 -0
  114. data/spec/models/spree/permission_sets/restricted_stock_transfer_display_spec.rb +50 -0
  115. data/spec/models/spree/permission_sets/restricted_stock_transfer_management_spec.rb +160 -0
  116. data/spec/models/spree/permission_sets/stock_display_spec.rb +24 -0
  117. data/spec/models/spree/permission_sets/stock_management_spec.rb +22 -0
  118. data/spec/models/spree/permission_sets/stock_transfer_display_spec.rb +24 -0
  119. data/spec/models/spree/permission_sets/stock_transfer_management_spec.rb +25 -0
  120. data/spec/models/spree/permission_sets/user_display_spec.rb +38 -0
  121. data/spec/models/spree/permission_sets/user_management_spec.rb +48 -0
  122. data/spec/models/spree/preference_spec.rb +80 -0
  123. data/spec/models/spree/preferences/configuration_spec.rb +30 -0
  124. data/spec/models/spree/preferences/preferable_spec.rb +294 -0
  125. data/spec/models/spree/preferences/scoped_store_spec.rb +60 -0
  126. data/spec/models/spree/preferences/static_model_preferences_spec.rb +78 -0
  127. data/spec/models/spree/preferences/statically_configurable_spec.rb +60 -0
  128. data/spec/models/spree/preferences/store_spec.rb +39 -0
  129. data/spec/models/spree/price_spec.rb +42 -0
  130. data/spec/models/spree/product/scopes_spec.rb +116 -0
  131. data/spec/models/spree/product_duplicator_spec.rb +103 -0
  132. data/spec/models/spree/product_filter_spec.rb +26 -0
  133. data/spec/models/spree/product_property_spec.rb +18 -0
  134. data/spec/models/spree/product_spec.rb +504 -0
  135. data/spec/models/spree/promotion/actions/create_adjustment_spec.rb +96 -0
  136. data/spec/models/spree/promotion/actions/create_item_adjustments_spec.rb +165 -0
  137. data/spec/models/spree/promotion/actions/create_quantity_adjustments_spec.rb +115 -0
  138. data/spec/models/spree/promotion/actions/free_shipping_spec.rb +40 -0
  139. data/spec/models/spree/promotion/rules/first_order_spec.rb +75 -0
  140. data/spec/models/spree/promotion/rules/first_repeat_purchase_since_spec.rb +69 -0
  141. data/spec/models/spree/promotion/rules/item_total_spec.rb +67 -0
  142. data/spec/models/spree/promotion/rules/nth_order_spec.rb +70 -0
  143. data/spec/models/spree/promotion/rules/one_use_per_user_spec.rb +42 -0
  144. data/spec/models/spree/promotion/rules/option_value_spec.rb +94 -0
  145. data/spec/models/spree/promotion/rules/product_spec.rb +143 -0
  146. data/spec/models/spree/promotion/rules/taxon_spec.rb +102 -0
  147. data/spec/models/spree/promotion/rules/user_logged_in_spec.rb +27 -0
  148. data/spec/models/spree/promotion/rules/user_spec.rb +37 -0
  149. data/spec/models/spree/promotion_builder_spec.rb +118 -0
  150. data/spec/models/spree/promotion_category_spec.rb +17 -0
  151. data/spec/models/spree/promotion_code/code_builder_spec.rb +79 -0
  152. data/spec/models/spree/promotion_code_spec.rb +187 -0
  153. data/spec/models/spree/promotion_handler/cart_spec.rb +130 -0
  154. data/spec/models/spree/promotion_handler/coupon_spec.rb +335 -0
  155. data/spec/models/spree/promotion_handler/free_shipping_spec.rb +47 -0
  156. data/spec/models/spree/promotion_handler/page_spec.rb +44 -0
  157. data/spec/models/spree/promotion_rule_spec.rb +28 -0
  158. data/spec/models/spree/promotion_spec.rb +776 -0
  159. data/spec/models/spree/refund_spec.rb +192 -0
  160. data/spec/models/spree/reimbursement/credit_spec.rb +36 -0
  161. data/spec/models/spree/reimbursement/reimbursement_type_engine_spec.rb +140 -0
  162. data/spec/models/spree/reimbursement/reimbursement_type_validator_spec.rb +83 -0
  163. data/spec/models/spree/reimbursement_performer_spec.rb +30 -0
  164. data/spec/models/spree/reimbursement_spec.rb +231 -0
  165. data/spec/models/spree/reimbursement_tax_calculator_spec.rb +51 -0
  166. data/spec/models/spree/reimbursement_type/credit_spec.rb +53 -0
  167. data/spec/models/spree/reimbursement_type/exchange_spec.rb +46 -0
  168. data/spec/models/spree/reimbursement_type/original_payment_spec.rb +107 -0
  169. data/spec/models/spree/reimbursement_type/store_credit_spec.rb +97 -0
  170. data/spec/models/spree/return_authorization_spec.rb +290 -0
  171. data/spec/models/spree/return_item/eligibility_validator/default_spec.rb +77 -0
  172. data/spec/models/spree/return_item/eligibility_validator/inventory_shipped_spec.rb +58 -0
  173. data/spec/models/spree/return_item/eligibility_validator/no_reimbursements_spec.rb +85 -0
  174. data/spec/models/spree/return_item/eligibility_validator/order_completed_spec.rb +32 -0
  175. data/spec/models/spree/return_item/eligibility_validator/rma_required_spec.rb +29 -0
  176. data/spec/models/spree/return_item/eligibility_validator/time_since_purchase_spec.rb +35 -0
  177. data/spec/models/spree/return_item/exchange_variant_eligibility/same_option_value_spec.rb +65 -0
  178. data/spec/models/spree/return_item/exchange_variant_eligibility/same_product_spec.rb +43 -0
  179. data/spec/models/spree/return_item_spec.rb +776 -0
  180. data/spec/models/spree/returns_calculator_spec.rb +14 -0
  181. data/spec/models/spree/shipment_spec.rb +753 -0
  182. data/spec/models/spree/shipping_calculator_spec.rb +45 -0
  183. data/spec/models/spree/shipping_manifest_spec.rb +94 -0
  184. data/spec/models/spree/shipping_method_spec.rb +88 -0
  185. data/spec/models/spree/shipping_rate_spec.rb +142 -0
  186. data/spec/models/spree/state_spec.rb +14 -0
  187. data/spec/models/spree/stock/availability_validator_spec.rb +83 -0
  188. data/spec/models/spree/stock/coordinator_spec.rb +116 -0
  189. data/spec/models/spree/stock/differentiator_spec.rb +39 -0
  190. data/spec/models/spree/stock/estimator_spec.rb +146 -0
  191. data/spec/models/spree/stock/inventory_unit_builder_spec.rb +38 -0
  192. data/spec/models/spree/stock/package_spec.rb +163 -0
  193. data/spec/models/spree/stock/packer_spec.rb +91 -0
  194. data/spec/models/spree/stock/prioritizer_spec.rb +125 -0
  195. data/spec/models/spree/stock/quantifier_spec.rb +115 -0
  196. data/spec/models/spree/stock/splitter/backordered_spec.rb +29 -0
  197. data/spec/models/spree/stock/splitter/base_spec.rb +21 -0
  198. data/spec/models/spree/stock/splitter/shipping_category_spec.rb +50 -0
  199. data/spec/models/spree/stock/splitter/weight_spec.rb +29 -0
  200. data/spec/models/spree/stock_item_spec.rb +444 -0
  201. data/spec/models/spree/stock_location_spec.rb +279 -0
  202. data/spec/models/spree/stock_movement_spec.rb +56 -0
  203. data/spec/models/spree/stock_transfer_spec.rb +290 -0
  204. data/spec/models/spree/store_credit_category_spec.rb +17 -0
  205. data/spec/models/spree/store_credit_event_spec.rb +314 -0
  206. data/spec/models/spree/store_credit_spec.rb +876 -0
  207. data/spec/models/spree/store_spec.rb +55 -0
  208. data/spec/models/spree/tax_category_spec.rb +27 -0
  209. data/spec/models/spree/tax_rate_spec.rb +378 -0
  210. data/spec/models/spree/taxon_spec.rb +74 -0
  211. data/spec/models/spree/taxonomy_spec.rb +18 -0
  212. data/spec/models/spree/tracker_spec.rb +21 -0
  213. data/spec/models/spree/transfer_item_spec.rb +264 -0
  214. data/spec/models/spree/unit_cancel_spec.rb +149 -0
  215. data/spec/models/spree/user_spec.rb +246 -0
  216. data/spec/models/spree/validations/db_maximum_length_validator_spec.rb +23 -0
  217. data/spec/models/spree/variant/scopes_spec.rb +55 -0
  218. data/spec/models/spree/variant_property_rule_condition_spec.rb +15 -0
  219. data/spec/models/spree/variant_property_rule_spec.rb +83 -0
  220. data/spec/models/spree/variant_property_rule_value_spec.rb +18 -0
  221. data/spec/models/spree/variant_spec.rb +601 -0
  222. data/spec/models/spree/zone_spec.rb +305 -0
  223. data/spec/spec_helper.rb +80 -0
  224. data/spec/support/big_decimal.rb +5 -0
  225. data/spec/support/concerns/default_price.rb +34 -0
  226. data/spec/support/dummy_ability.rb +4 -0
  227. data/spec/support/test_gateway.rb +2 -0
  228. metadata +242 -2
@@ -0,0 +1,91 @@
1
+ require 'spec_helper'
2
+
3
+ module Spree
4
+ module Stock
5
+ describe Packer, :type => :model do
6
+ let!(:inventory_units) { 5.times.map { build(:inventory_unit) } }
7
+ let(:stock_location) { create(:stock_location) }
8
+
9
+ subject { Packer.new(stock_location, inventory_units) }
10
+
11
+ context 'packages' do
12
+ it 'builds an array of packages' do
13
+ packages = subject.packages
14
+ expect(packages.size).to eq 1
15
+ expect(packages.first.contents.size).to eq 5
16
+ end
17
+
18
+ it 'allows users to set splitters to an empty array' do
19
+ packages = Packer.new(stock_location, inventory_units, []).packages
20
+ expect(packages.size).to eq 1
21
+ end
22
+ end
23
+
24
+ context 'default_package' do
25
+ it 'contains all the items' do
26
+ package = subject.default_package
27
+ expect(package.contents.size).to eq 5
28
+ end
29
+
30
+ it 'variants are added as backordered without enough on_hand' do
31
+ expect(stock_location).to receive(:fill_status).exactly(5).times.and_return(
32
+ *(Array.new(3, [1,0]) + Array.new(2, [0,1]))
33
+ )
34
+
35
+ package = subject.default_package
36
+ expect(package.on_hand.size).to eq 3
37
+ expect(package.backordered.size).to eq 2
38
+ end
39
+
40
+ context "location doesn't have order items in stock" do
41
+ let(:stock_location) { create(:stock_location, propagate_all_variants: false) }
42
+ let(:packer) { Packer.new(stock_location, inventory_units) }
43
+
44
+ it "builds an empty package" do
45
+ expect(packer.default_package.contents).to be_empty
46
+ end
47
+ end
48
+
49
+ context "not enough on hand and not backorderable" do
50
+ let(:packer) { Packer.new(stock_location, inventory_units) }
51
+
52
+ before do
53
+ stock_location.stock_items.update_all(backorderable: false)
54
+ stock_location.stock_items.each { |si| si.set_count_on_hand(0) }
55
+ end
56
+
57
+ it "raises an error" do
58
+ expect { packer.default_package }.to raise_error Spree::Order::InsufficientStock
59
+ end
60
+ end
61
+
62
+ context "doesn't track inventory levels" do
63
+ let(:variant) { build(:variant) }
64
+ let(:order) { build(:order_with_line_items, line_items_count: 1) }
65
+ let(:line_item) { order.line_items.first }
66
+ let(:inventory_units) {
67
+ 30.times.map do
68
+ build(
69
+ :inventory_unit,
70
+ order: order,
71
+ line_item: line_item,
72
+ variant: variant,
73
+ )
74
+ end
75
+ }
76
+
77
+ before { Config.track_inventory_levels = false }
78
+
79
+ it "doesn't bother stock items status in stock location" do
80
+ expect(subject.stock_location).not_to receive(:fill_status)
81
+ subject.default_package
82
+ end
83
+
84
+ it "still creates package with proper quantity" do
85
+ expect(subject.default_package.quantity).to eql 30
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,125 @@
1
+ require 'spec_helper'
2
+
3
+ module Spree
4
+ module Stock
5
+ describe Prioritizer, :type => :model do
6
+ let(:order) { mock_model(Order) }
7
+ let(:stock_location) { build(:stock_location) }
8
+ let(:variant) { build(:variant) }
9
+
10
+ def inventory_units
11
+ @inventory_units ||= []
12
+ end
13
+
14
+ def build_inventory_unit
15
+ mock_model(InventoryUnit, variant: variant).tap do |unit|
16
+ inventory_units << unit
17
+ end
18
+ end
19
+
20
+ def pack
21
+ package = Package.new(order)
22
+ yield(package) if block_given?
23
+ package
24
+ end
25
+
26
+ it 'keeps a single package' do
27
+ package1 = pack do |package|
28
+ package.add build_inventory_unit
29
+ package.add build_inventory_unit
30
+ end
31
+
32
+ packages = [package1]
33
+ prioritizer = Prioritizer.new(inventory_units, packages)
34
+ packages = prioritizer.prioritized_packages
35
+ expect(packages.size).to eq 1
36
+ end
37
+
38
+ it 'removes duplicate packages' do
39
+ package1 = pack do |package|
40
+ package.add build_inventory_unit
41
+ package.add build_inventory_unit
42
+ end
43
+
44
+ package2 = pack do |package|
45
+ package.add inventory_units.first
46
+ package.add inventory_units.last
47
+ end
48
+
49
+ packages = [package1, package2]
50
+ prioritizer = Prioritizer.new(inventory_units, packages)
51
+ packages = prioritizer.prioritized_packages
52
+ expect(packages.size).to eq 1
53
+ end
54
+
55
+ it 'split over 2 packages' do
56
+ package1 = pack do |package|
57
+ package.add build_inventory_unit
58
+ end
59
+ package2 = pack do |package|
60
+ package.add build_inventory_unit
61
+ end
62
+
63
+ packages = [package1, package2]
64
+ prioritizer = Prioritizer.new(inventory_units, packages)
65
+ packages = prioritizer.prioritized_packages
66
+ expect(packages.size).to eq 2
67
+ end
68
+
69
+ it '1st has some, 2nd has remaining' do
70
+ 5.times { build_inventory_unit }
71
+
72
+ package1 = pack do |package|
73
+ 2.times { |i| package.add inventory_units[i] }
74
+ end
75
+ package2 = pack do |package|
76
+ 5.times { |i| package.add inventory_units[i] }
77
+ end
78
+
79
+ packages = [package1, package2]
80
+ prioritizer = Prioritizer.new(inventory_units, packages)
81
+ packages = prioritizer.prioritized_packages
82
+ expect(packages.count).to eq 2
83
+ expect(packages[0].quantity).to eq 2
84
+ expect(packages[1].quantity).to eq 3
85
+ end
86
+
87
+ it '1st has backorder, 2nd has some' do
88
+ 5.times { build_inventory_unit }
89
+
90
+ package1 = pack do |package|
91
+ 5.times { |i| package.add inventory_units[i], :backordered }
92
+ end
93
+ package2 = pack do |package|
94
+ 2.times { |i| package.add inventory_units[i] }
95
+ end
96
+
97
+ packages = [package1, package2]
98
+ prioritizer = Prioritizer.new(inventory_units, packages)
99
+ packages = prioritizer.prioritized_packages
100
+
101
+ expect(packages[0].quantity(:backordered)).to eq 3
102
+ expect(packages[1].quantity(:on_hand)).to eq 2
103
+ end
104
+
105
+ it '1st has backorder, 2nd has all' do
106
+ 5.times { build_inventory_unit }
107
+
108
+ package1 = pack do |package|
109
+ 3.times { |i| package.add inventory_units[i], :backordered }
110
+ end
111
+ package2 = pack do |package|
112
+ 5.times { |i| package.add inventory_units[i] }
113
+ end
114
+
115
+ packages = [package1, package2]
116
+ prioritizer = Prioritizer.new(inventory_units, packages)
117
+ packages = prioritizer.prioritized_packages
118
+ expect(packages[0]).to eq package2
119
+ expect(packages[1]).to be_nil
120
+ expect(packages[0].quantity(:backordered)).to eq 0
121
+ expect(packages[0].quantity(:on_hand)).to eq 5
122
+ end
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,115 @@
1
+ require 'spec_helper'
2
+
3
+ shared_examples_for 'unlimited supply' do
4
+ it 'can_supply? any amount' do
5
+ expect(subject.can_supply?(1)).to eq true
6
+ expect(subject.can_supply?(101)).to eq true
7
+ expect(subject.can_supply?(100_001)).to eq true
8
+ end
9
+ end
10
+
11
+ module Spree
12
+ module Stock
13
+ describe Quantifier, :type => :model do
14
+
15
+ let(:target_stock_location) { nil }
16
+ let!(:stock_location) { create :stock_location_with_items }
17
+ let!(:stock_item) { stock_location.stock_items.order(:id).first }
18
+
19
+ subject { described_class.new(stock_item.variant, target_stock_location) }
20
+
21
+ specify { expect(subject.stock_items).to eq([stock_item]) }
22
+
23
+ context 'with a single stock location/item' do
24
+ it 'total_on_hand should match stock_item' do
25
+ expect(subject.total_on_hand).to eq stock_item.count_on_hand
26
+ end
27
+
28
+ context 'when track_inventory_levels is false' do
29
+ before { configure_spree_preferences { |config| config.track_inventory_levels = false } }
30
+
31
+ specify { expect(subject.total_on_hand).to eq(Float::INFINITY) }
32
+
33
+ it_should_behave_like 'unlimited supply'
34
+ end
35
+
36
+ context 'when variant inventory tracking is off' do
37
+ before { stock_item.variant.track_inventory = false }
38
+
39
+ specify { expect(subject.total_on_hand).to eq(Float::INFINITY) }
40
+
41
+ it_should_behave_like 'unlimited supply'
42
+ end
43
+
44
+ context 'when stock item allows backordering' do
45
+ specify { expect(subject.backorderable?).to be true }
46
+
47
+ it_should_behave_like 'unlimited supply'
48
+ end
49
+
50
+ context 'when stock item prevents backordering' do
51
+ before { stock_item.update_attributes(backorderable: false) }
52
+
53
+ specify { expect(subject.backorderable?).to be false }
54
+
55
+ it 'can_supply? only upto total_on_hand' do
56
+ expect(subject.can_supply?(1)).to be true
57
+ expect(subject.can_supply?(10)).to be true
58
+ expect(subject.can_supply?(11)).to be false
59
+ end
60
+ end
61
+
62
+ end
63
+
64
+ context 'with multiple stock locations/items' do
65
+ let!(:stock_location_2) { create :stock_location }
66
+ let!(:stock_location_3) { create :stock_location, active: false }
67
+
68
+ before do
69
+ stock_location_2.stock_items.where(variant_id: stock_item.variant).update_all(count_on_hand: 5, backorderable: false)
70
+ stock_location_3.stock_items.where(variant_id: stock_item.variant).update_all(count_on_hand: 5, backorderable: false)
71
+ end
72
+
73
+ it 'total_on_hand should total all active stock_items' do
74
+ expect(subject.total_on_hand).to eq(15)
75
+ end
76
+
77
+ context 'when any stock item allows backordering' do
78
+ specify { expect(subject.backorderable?).to be true }
79
+
80
+ it_should_behave_like 'unlimited supply'
81
+ end
82
+
83
+ context 'when all stock items prevent backordering' do
84
+ before { stock_item.update_attributes(backorderable: false) }
85
+
86
+ specify { expect(subject.backorderable?).to be false }
87
+
88
+ it 'can_supply? upto total_on_hand' do
89
+ expect(subject.can_supply?(1)).to be true
90
+ expect(subject.can_supply?(15)).to be true
91
+ expect(subject.can_supply?(16)).to be false
92
+ end
93
+ end
94
+
95
+ end
96
+
97
+ context 'with a specific stock location' do
98
+ let!(:stock_location_2) { create :stock_location }
99
+ let!(:stock_location_3) { create :stock_location, active: false }
100
+ let(:target_stock_location) { stock_location_3 }
101
+
102
+ before do
103
+ Spree::StockItem.update_all(count_on_hand: 0, backorderable: false)
104
+ stock_location_3.stock_items.where(variant_id: stock_item.variant).update_all(count_on_hand: 5, backorderable: false)
105
+ end
106
+
107
+ it 'can_supply? only upto total_on_hand' do
108
+ expect(subject.can_supply?(5)).to eq true
109
+ expect(subject.can_supply?(6)).to eq false
110
+ end
111
+ end
112
+
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ module Spree
4
+ module Stock
5
+ module Splitter
6
+ describe Backordered, :type => :model do
7
+ let(:variant) { build(:variant) }
8
+
9
+ let(:packer) { build(:stock_packer) }
10
+
11
+ subject { Backordered.new(packer) }
12
+
13
+ it 'splits packages by status' do
14
+ package = Package.new(packer.stock_location)
15
+ 4.times { package.add build(:inventory_unit, variant: variant) }
16
+ 5.times { package.add build(:inventory_unit, variant: variant), :backordered }
17
+
18
+ packages = subject.split([package])
19
+ expect(packages.count).to eq 2
20
+ expect(packages.first.quantity).to eq 4
21
+ expect(packages.first.on_hand.count).to eq 4
22
+ expect(packages.first.backordered.count).to eq 0
23
+
24
+ expect(packages[1].contents.count).to eq 5
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ module Spree
4
+ module Stock
5
+ module Splitter
6
+ describe Base, :type => :model do
7
+ let(:packer) { build(:stock_packer) }
8
+
9
+ it 'continues to splitter chain' do
10
+ splitter1 = Base.new(packer)
11
+ splitter2 = Base.new(packer, splitter1)
12
+ packages = []
13
+
14
+ expect(splitter1).to receive(:split).with(packages)
15
+ splitter2.split(packages)
16
+ end
17
+
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+
3
+ module Spree
4
+ module Stock
5
+ module Splitter
6
+ describe ShippingCategory, :type => :model do
7
+
8
+ let(:order) { create(:order_with_line_items, line_items_count: 1) }
9
+ let(:line_item) { order.line_items.first }
10
+ let(:variant1) { build(:variant) }
11
+ let(:variant2) { build(:variant) }
12
+ let(:shipping_category_1) { create(:shipping_category, name: 'A') }
13
+ let(:shipping_category_2) { create(:shipping_category, name: 'B') }
14
+
15
+ def inventory_unit1
16
+ build(:inventory_unit, variant: variant1, order: order, line_item: line_item).tap do |inventory_unit|
17
+ inventory_unit.variant.product.shipping_category = shipping_category_1
18
+ end
19
+ end
20
+
21
+ def inventory_unit2
22
+ build(:inventory_unit, variant: variant2, order: order, line_item: line_item).tap do |inventory_unit|
23
+ inventory_unit.variant.product.shipping_category = shipping_category_2
24
+ end
25
+ end
26
+
27
+ let(:packer) { build(:stock_packer) }
28
+
29
+ subject { ShippingCategory.new(packer) }
30
+
31
+ it 'splits each package by shipping category' do
32
+ package1 = Package.new(packer.stock_location)
33
+ 4.times { package1.add inventory_unit1 }
34
+ 8.times { package1.add inventory_unit2 }
35
+
36
+ package2 = Package.new(packer.stock_location)
37
+ 6.times { package2.add inventory_unit1 }
38
+ 9.times { package2.add inventory_unit2, :backordered }
39
+
40
+ packages = subject.split([package1, package2])
41
+ expect(packages[0].quantity).to eq 4
42
+ expect(packages[1].quantity).to eq 8
43
+ expect(packages[2].quantity).to eq 6
44
+ expect(packages[3].quantity).to eq 9
45
+ end
46
+
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ module Spree
4
+ module Stock
5
+ module Splitter
6
+ describe Weight, :type => :model do
7
+ let(:packer) { build(:stock_packer) }
8
+ let(:variant) { build(:base_variant, :weight => 100) }
9
+
10
+ subject { Weight.new(packer) }
11
+
12
+ it 'splits and keeps splitting until all packages are underweight' do
13
+ package = Package.new(packer.stock_location)
14
+ 4.times { package.add build(:inventory_unit, variant: variant) }
15
+ packages = subject.split([package])
16
+ expect(packages.size).to eq 4
17
+ end
18
+
19
+ it 'handles packages that can not be reduced' do
20
+ package = Package.new(packer.stock_location)
21
+ allow(variant).to receive_messages(:weight => 200)
22
+ 2.times { package.add build(:inventory_unit, variant: variant) }
23
+ packages = subject.split([package])
24
+ expect(packages.size).to eq 2
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end