solidus_core 1.0.2 → 1.0.3

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 (216) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1 -0
  3. data/Gemfile +3 -0
  4. data/Rakefile +16 -0
  5. data/script/rails +9 -0
  6. data/solidus_core.gemspec +48 -0
  7. data/spec/fixtures/thinking-cat.jpg +0 -0
  8. data/spec/helpers/base_helper_spec.rb +173 -0
  9. data/spec/helpers/order_helper_spec.rb +12 -0
  10. data/spec/helpers/products_helper_spec.rb +220 -0
  11. data/spec/helpers/taxons_helper_spec.rb +17 -0
  12. data/spec/lib/calculated_adjustments_spec.rb +7 -0
  13. data/spec/lib/i18n_spec.rb +123 -0
  14. data/spec/lib/search/base_spec.rb +86 -0
  15. data/spec/lib/search/variant_spec.rb +92 -0
  16. data/spec/lib/spree/core/controller_helpers/auth_spec.rb +66 -0
  17. data/spec/lib/spree/core/controller_helpers/order_spec.rb +92 -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 +22 -0
  23. data/spec/lib/spree/core/importer/order_spec.rb +431 -0
  24. data/spec/lib/spree/core/role_configuration_spec.rb +138 -0
  25. data/spec/lib/spree/core/validators/email_spec.rb +48 -0
  26. data/spec/lib/spree/localized_number_spec.rb +38 -0
  27. data/spec/lib/spree/migrations_spec.rb +36 -0
  28. data/spec/lib/spree/money_spec.rb +127 -0
  29. data/spec/lib/tasks/exchanges_spec.rb +231 -0
  30. data/spec/lib/tasks/migrations/copy_shipped_shipments_to_cartons_spec.rb +115 -0
  31. data/spec/lib/tasks/order_capturing_spec.rb +56 -0
  32. data/spec/mailers/carton_mailer_spec.rb +43 -0
  33. data/spec/mailers/order_mailer_spec.rb +122 -0
  34. data/spec/mailers/reimbursement_mailer_spec.rb +40 -0
  35. data/spec/mailers/test_mailer_spec.rb +15 -0
  36. data/spec/models/spree/ability_spec.rb +276 -0
  37. data/spec/models/spree/address_spec.rb +250 -0
  38. data/spec/models/spree/adjustment_reason_spec.rb +13 -0
  39. data/spec/models/spree/adjustment_spec.rb +177 -0
  40. data/spec/models/spree/app_configuration_spec.rb +20 -0
  41. data/spec/models/spree/asset_spec.rb +24 -0
  42. data/spec/models/spree/calculator/default_tax_spec.rb +127 -0
  43. data/spec/models/spree/calculator/flat_percent_item_total_spec.rb +25 -0
  44. data/spec/models/spree/calculator/flat_rate_spec.rb +47 -0
  45. data/spec/models/spree/calculator/flexi_rate_spec.rb +41 -0
  46. data/spec/models/spree/calculator/percent_on_line_item_spec.rb +15 -0
  47. data/spec/models/spree/calculator/price_sack_spec.rb +30 -0
  48. data/spec/models/spree/calculator/refunds/default_refund_amount_spec.rb +51 -0
  49. data/spec/models/spree/calculator/shipping/flat_percent_item_total_spec.rb +23 -0
  50. data/spec/models/spree/calculator/shipping/flat_rate_spec.rb +13 -0
  51. data/spec/models/spree/calculator/shipping/flexi_rate_spec.rb +52 -0
  52. data/spec/models/spree/calculator/shipping/per_item_spec.rb +20 -0
  53. data/spec/models/spree/calculator/shipping/price_sack_spec.rb +30 -0
  54. data/spec/models/spree/calculator/tiered_flat_rate_spec.rb +36 -0
  55. data/spec/models/spree/calculator/tiered_percent_spec.rb +47 -0
  56. data/spec/models/spree/calculator_spec.rb +36 -0
  57. data/spec/models/spree/carton_spec.rb +133 -0
  58. data/spec/models/spree/classification_spec.rb +15 -0
  59. data/spec/models/spree/concerns/display_money_spec.rb +43 -0
  60. data/spec/models/spree/concerns/user_methods_spec.rb +41 -0
  61. data/spec/models/spree/credit_card_spec.rb +334 -0
  62. data/spec/models/spree/customer_return_spec.rb +276 -0
  63. data/spec/models/spree/exchange_spec.rb +79 -0
  64. data/spec/models/spree/gateway/bogus_simple.rb +20 -0
  65. data/spec/models/spree/gateway/bogus_spec.rb +13 -0
  66. data/spec/models/spree/gateway_spec.rb +82 -0
  67. data/spec/models/spree/inventory_unit_spec.rb +307 -0
  68. data/spec/models/spree/item_adjustments_spec.rb +256 -0
  69. data/spec/models/spree/line_item_spec.rb +191 -0
  70. data/spec/models/spree/option_type_spec.rb +14 -0
  71. data/spec/models/spree/option_value_spec.rb +22 -0
  72. data/spec/models/spree/order/address_spec.rb +50 -0
  73. data/spec/models/spree/order/adjustments_spec.rb +39 -0
  74. data/spec/models/spree/order/callbacks_spec.rb +42 -0
  75. data/spec/models/spree/order/checkout_spec.rb +902 -0
  76. data/spec/models/spree/order/currency_updater_spec.rb +32 -0
  77. data/spec/models/spree/order/finalizing_spec.rb +111 -0
  78. data/spec/models/spree/order/payment_spec.rb +210 -0
  79. data/spec/models/spree/order/risk_assessment_spec.rb +68 -0
  80. data/spec/models/spree/order/state_machine_spec.rb +221 -0
  81. data/spec/models/spree/order/tax_spec.rb +84 -0
  82. data/spec/models/spree/order/totals_spec.rb +24 -0
  83. data/spec/models/spree/order/updating_spec.rb +18 -0
  84. data/spec/models/spree/order/validations_spec.rb +15 -0
  85. data/spec/models/spree/order_cancellations_spec.rb +120 -0
  86. data/spec/models/spree/order_capturing_spec.rb +116 -0
  87. data/spec/models/spree/order_contents_spec.rb +265 -0
  88. data/spec/models/spree/order_inventory_spec.rb +228 -0
  89. data/spec/models/spree/order_mutex_spec.rb +85 -0
  90. data/spec/models/spree/order_promotion_spec.rb +31 -0
  91. data/spec/models/spree/order_shipping_spec.rb +247 -0
  92. data/spec/models/spree/order_spec.rb +1412 -0
  93. data/spec/models/spree/order_stock_location_spec.rb +18 -0
  94. data/spec/models/spree/order_updater_spec.rb +299 -0
  95. data/spec/models/spree/payment_method/store_credit_spec.rb +294 -0
  96. data/spec/models/spree/payment_method_spec.rb +96 -0
  97. data/spec/models/spree/payment_spec.rb +1044 -0
  98. data/spec/models/spree/permission_sets/base_spec.rb +12 -0
  99. data/spec/models/spree/permission_sets/configuration_display.rb +82 -0
  100. data/spec/models/spree/permission_sets/configuration_management_spec.rb +50 -0
  101. data/spec/models/spree/permission_sets/dashboard_display_spec.rb +22 -0
  102. data/spec/models/spree/permission_sets/order_display_spec.rb +49 -0
  103. data/spec/models/spree/permission_sets/order_management_spec.rb +36 -0
  104. data/spec/models/spree/permission_sets/product_display_spec.rb +60 -0
  105. data/spec/models/spree/permission_sets/product_management_spec.rb +40 -0
  106. data/spec/models/spree/permission_sets/promotion_display_spec.rb +34 -0
  107. data/spec/models/spree/permission_sets/promotion_management_spec.rb +26 -0
  108. data/spec/models/spree/permission_sets/report_display_spec.rb +24 -0
  109. data/spec/models/spree/permission_sets/restricted_transfer_management_spec.rb +132 -0
  110. data/spec/models/spree/permission_sets/stock_display_spec.rb +26 -0
  111. data/spec/models/spree/permission_sets/stock_management_spec.rb +24 -0
  112. data/spec/models/spree/permission_sets/user_display_spec.rb +36 -0
  113. data/spec/models/spree/permission_sets/user_management_spec.rb +28 -0
  114. data/spec/models/spree/preference_spec.rb +80 -0
  115. data/spec/models/spree/preferences/configuration_spec.rb +30 -0
  116. data/spec/models/spree/preferences/preferable_spec.rb +294 -0
  117. data/spec/models/spree/preferences/scoped_store_spec.rb +58 -0
  118. data/spec/models/spree/preferences/static_model_preferences_spec.rb +78 -0
  119. data/spec/models/spree/preferences/statically_configurable_spec.rb +60 -0
  120. data/spec/models/spree/preferences/store_spec.rb +39 -0
  121. data/spec/models/spree/price_spec.rb +42 -0
  122. data/spec/models/spree/product/scopes_spec.rb +148 -0
  123. data/spec/models/spree/product_duplicator_spec.rb +103 -0
  124. data/spec/models/spree/product_filter_spec.rb +26 -0
  125. data/spec/models/spree/product_property_spec.rb +20 -0
  126. data/spec/models/spree/product_spec.rb +437 -0
  127. data/spec/models/spree/promotion/actions/create_adjustment_spec.rb +96 -0
  128. data/spec/models/spree/promotion/actions/create_item_adjustments_spec.rb +165 -0
  129. data/spec/models/spree/promotion/actions/create_quantity_adjustments_spec.rb +115 -0
  130. data/spec/models/spree/promotion/actions/free_shipping_spec.rb +40 -0
  131. data/spec/models/spree/promotion/rules/first_order_spec.rb +75 -0
  132. data/spec/models/spree/promotion/rules/item_total_spec.rb +67 -0
  133. data/spec/models/spree/promotion/rules/nth_order_spec.rb +70 -0
  134. data/spec/models/spree/promotion/rules/one_use_per_user_spec.rb +42 -0
  135. data/spec/models/spree/promotion/rules/option_value_spec.rb +94 -0
  136. data/spec/models/spree/promotion/rules/product_spec.rb +143 -0
  137. data/spec/models/spree/promotion/rules/taxon_spec.rb +102 -0
  138. data/spec/models/spree/promotion/rules/user_logged_in_spec.rb +27 -0
  139. data/spec/models/spree/promotion/rules/user_spec.rb +37 -0
  140. data/spec/models/spree/promotion_builder_spec.rb +118 -0
  141. data/spec/models/spree/promotion_category_spec.rb +17 -0
  142. data/spec/models/spree/promotion_code/code_builder_spec.rb +79 -0
  143. data/spec/models/spree/promotion_code_spec.rb +187 -0
  144. data/spec/models/spree/promotion_handler/cart_spec.rb +114 -0
  145. data/spec/models/spree/promotion_handler/coupon_spec.rb +335 -0
  146. data/spec/models/spree/promotion_handler/free_shipping_spec.rb +47 -0
  147. data/spec/models/spree/promotion_handler/page_spec.rb +44 -0
  148. data/spec/models/spree/promotion_rule_spec.rb +28 -0
  149. data/spec/models/spree/promotion_spec.rb +767 -0
  150. data/spec/models/spree/refund_spec.rb +204 -0
  151. data/spec/models/spree/reimbursement/credit_spec.rb +36 -0
  152. data/spec/models/spree/reimbursement/reimbursement_type_engine_spec.rb +140 -0
  153. data/spec/models/spree/reimbursement/reimbursement_type_validator_spec.rb +83 -0
  154. data/spec/models/spree/reimbursement_performer_spec.rb +30 -0
  155. data/spec/models/spree/reimbursement_spec.rb +231 -0
  156. data/spec/models/spree/reimbursement_tax_calculator_spec.rb +51 -0
  157. data/spec/models/spree/reimbursement_type/credit_spec.rb +53 -0
  158. data/spec/models/spree/reimbursement_type/exchange_spec.rb +46 -0
  159. data/spec/models/spree/reimbursement_type/original_payment_spec.rb +107 -0
  160. data/spec/models/spree/reimbursement_type/store_credit_spec.rb +97 -0
  161. data/spec/models/spree/return_authorization_spec.rb +290 -0
  162. data/spec/models/spree/return_item/eligibility_validator/default_spec.rb +77 -0
  163. data/spec/models/spree/return_item/eligibility_validator/inventory_shipped_spec.rb +58 -0
  164. data/spec/models/spree/return_item/eligibility_validator/no_reimbursements_spec.rb +85 -0
  165. data/spec/models/spree/return_item/eligibility_validator/order_completed_spec.rb +32 -0
  166. data/spec/models/spree/return_item/eligibility_validator/rma_required_spec.rb +29 -0
  167. data/spec/models/spree/return_item/eligibility_validator/time_since_purchase_spec.rb +35 -0
  168. data/spec/models/spree/return_item/exchange_variant_eligibility/same_option_value_spec.rb +65 -0
  169. data/spec/models/spree/return_item/exchange_variant_eligibility/same_product_spec.rb +43 -0
  170. data/spec/models/spree/return_item_spec.rb +775 -0
  171. data/spec/models/spree/returns_calculator_spec.rb +14 -0
  172. data/spec/models/spree/shipment_spec.rb +709 -0
  173. data/spec/models/spree/shipping_calculator_spec.rb +45 -0
  174. data/spec/models/spree/shipping_method_spec.rb +88 -0
  175. data/spec/models/spree/shipping_rate_spec.rb +142 -0
  176. data/spec/models/spree/state_spec.rb +14 -0
  177. data/spec/models/spree/stock/availability_validator_spec.rb +83 -0
  178. data/spec/models/spree/stock/coordinator_spec.rb +116 -0
  179. data/spec/models/spree/stock/differentiator_spec.rb +39 -0
  180. data/spec/models/spree/stock/estimator_spec.rb +146 -0
  181. data/spec/models/spree/stock/inventory_unit_builder_spec.rb +38 -0
  182. data/spec/models/spree/stock/package_spec.rb +163 -0
  183. data/spec/models/spree/stock/packer_spec.rb +91 -0
  184. data/spec/models/spree/stock/prioritizer_spec.rb +125 -0
  185. data/spec/models/spree/stock/quantifier_spec.rb +115 -0
  186. data/spec/models/spree/stock/splitter/backordered_spec.rb +29 -0
  187. data/spec/models/spree/stock/splitter/base_spec.rb +21 -0
  188. data/spec/models/spree/stock/splitter/shipping_category_spec.rb +50 -0
  189. data/spec/models/spree/stock/splitter/weight_spec.rb +29 -0
  190. data/spec/models/spree/stock_item_spec.rb +426 -0
  191. data/spec/models/spree/stock_location_spec.rb +279 -0
  192. data/spec/models/spree/stock_movement_spec.rb +56 -0
  193. data/spec/models/spree/stock_transfer_spec.rb +290 -0
  194. data/spec/models/spree/store_credit_category_spec.rb +17 -0
  195. data/spec/models/spree/store_credit_event_spec.rb +314 -0
  196. data/spec/models/spree/store_credit_spec.rb +876 -0
  197. data/spec/models/spree/store_spec.rb +55 -0
  198. data/spec/models/spree/tax_category_spec.rb +27 -0
  199. data/spec/models/spree/tax_rate_spec.rb +378 -0
  200. data/spec/models/spree/taxon_spec.rb +74 -0
  201. data/spec/models/spree/taxonomy_spec.rb +18 -0
  202. data/spec/models/spree/tracker_spec.rb +21 -0
  203. data/spec/models/spree/transfer_item_spec.rb +264 -0
  204. data/spec/models/spree/unit_cancel_spec.rb +148 -0
  205. data/spec/models/spree/user_spec.rb +223 -0
  206. data/spec/models/spree/validations/db_maximum_length_validator_spec.rb +23 -0
  207. data/spec/models/spree/variant/scopes_spec.rb +55 -0
  208. data/spec/models/spree/variant_spec.rb +546 -0
  209. data/spec/models/spree/zone_spec.rb +305 -0
  210. data/spec/spec_helper.rb +78 -0
  211. data/spec/support/big_decimal.rb +5 -0
  212. data/spec/support/concerns/default_price.rb +34 -0
  213. data/spec/support/dummy_ability.rb +4 -0
  214. data/spec/support/test_gateway.rb +2 -0
  215. metadata +229 -3
  216. data/lib/spree/testing_support/rspec-activemodel-mocks_patch.rb +0 -8
@@ -0,0 +1,74 @@
1
+ # coding: UTF-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Spree::Taxon, :type => :model do
6
+ let(:taxon) { FactoryGirl.build(:taxon, :name => "Ruby on Rails") }
7
+
8
+ describe '#to_param' do
9
+ subject { super().to_param }
10
+ it { is_expected.to eql taxon.permalink }
11
+ end
12
+
13
+ context "set_permalink" do
14
+
15
+ it "should set permalink correctly when no parent present" do
16
+ taxon.set_permalink
17
+ expect(taxon.permalink).to eql "ruby-on-rails"
18
+ end
19
+
20
+ it "should support Chinese characters" do
21
+ taxon.name = "你好"
22
+ taxon.set_permalink
23
+ expect(taxon.permalink).to eql 'ni-hao'
24
+ end
25
+
26
+ context "with parent taxon" do
27
+ let(:parent) { FactoryGirl.build(:taxon, :permalink => "brands") }
28
+ before { allow(taxon).to receive_messages parent: parent }
29
+
30
+ it "should set permalink correctly when taxon has parent" do
31
+ taxon.set_permalink
32
+ expect(taxon.permalink).to eql "brands/ruby-on-rails"
33
+ end
34
+
35
+ it "should set permalink correctly with existing permalink present" do
36
+ taxon.permalink = "b/rubyonrails"
37
+ taxon.set_permalink
38
+ expect(taxon.permalink).to eql "brands/rubyonrails"
39
+ end
40
+
41
+ it "should support Chinese characters" do
42
+ taxon.name = "我"
43
+ taxon.set_permalink
44
+ expect(taxon.permalink).to eql "brands/wo"
45
+ end
46
+
47
+ # Regression test for #3390
48
+ context "setting a new node sibling position via :child_index=" do
49
+ let(:idx) { rand(0..100) }
50
+ before { allow(parent).to receive(:move_to_child_with_index) }
51
+
52
+ context "taxon is not new" do
53
+ before { allow(taxon).to receive(:new_record?).and_return(false) }
54
+
55
+ it "passes the desired index move_to_child_with_index of :parent " do
56
+ expect(taxon).to receive(:move_to_child_with_index).with(parent, idx)
57
+
58
+ taxon.child_index = idx
59
+ end
60
+ end
61
+ end
62
+
63
+ end
64
+ end
65
+
66
+ # Regression test for #2620
67
+ context "creating a child node using first_or_create" do
68
+ let(:taxonomy) { create(:taxonomy) }
69
+
70
+ it "does not error out" do
71
+ expect { taxonomy.root.children.unscoped.where(:name => "Some name").first_or_create }.not_to raise_error
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Taxonomy, :type => :model do
4
+ context "#destroy" do
5
+ before do
6
+ @taxonomy = create(:taxonomy)
7
+ @root_taxon = @taxonomy.root
8
+ @child_taxon = create(:taxon, :taxonomy_id => @taxonomy.id, :parent => @root_taxon)
9
+ end
10
+
11
+ it "should destroy all associated taxons" do
12
+ @taxonomy.destroy
13
+ expect{ Spree::Taxon.find(@root_taxon.id) }.to raise_error(ActiveRecord::RecordNotFound)
14
+ expect{ Spree::Taxon.find(@child_taxon.id) }.to raise_error(ActiveRecord::RecordNotFound)
15
+ end
16
+ end
17
+ end
18
+
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Tracker, :type => :model do
4
+ describe "current" do
5
+ before(:each) { @tracker = create(:tracker) }
6
+
7
+ it "returns the first active tracker for the environment" do
8
+ expect(Spree::Tracker.current).to eq(@tracker)
9
+ end
10
+
11
+ it "does not return a tracker with a blank analytics_id" do
12
+ @tracker.update_attribute(:analytics_id, '')
13
+ expect(Spree::Tracker.current).to be_nil
14
+ end
15
+
16
+ it "does not return an inactive tracker" do
17
+ @tracker.update_attribute(:active, false)
18
+ expect(Spree::Tracker.current).to be_nil
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,264 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::TransferItem do
4
+ let(:stock_location) { create(:stock_location, name: "Warehouse") }
5
+ let(:stock_transfer) { create(:stock_transfer_with_items, source_location: stock_location) }
6
+ let(:transfer_item) { stock_transfer.transfer_items.first }
7
+
8
+ subject { transfer_item }
9
+
10
+ describe "validation" do
11
+ before do
12
+ transfer_item.assign_attributes(expected_quantity: expected_quantity, received_quantity: received_quantity)
13
+ end
14
+
15
+ describe "expected vs received quantity" do
16
+ context "expected quantity is the same as the received quantity" do
17
+ let(:expected_quantity) { 1 }
18
+ let(:received_quantity) { 1 }
19
+ it { is_expected.to be_valid }
20
+ end
21
+
22
+ context "expected quantity is larger than the received quantity" do
23
+ let(:expected_quantity) { 3 }
24
+ let(:received_quantity) { 1 }
25
+ it { is_expected.to be_valid }
26
+ end
27
+
28
+ context "expected quantity is lower than the received quantity" do
29
+ let(:expected_quantity) { 1 }
30
+ let(:received_quantity) { 3 }
31
+ it { is_expected.to_not be_valid }
32
+ end
33
+ end
34
+
35
+ describe "numericality" do
36
+ context "expected_quantity is less than 0" do
37
+ let(:expected_quantity) { -1 }
38
+ let(:received_quantity) { 3 }
39
+ it { is_expected.to_not be_valid }
40
+ end
41
+
42
+ context "received_quantity is less than 0" do
43
+ let(:expected_quantity) { 1 }
44
+ let(:received_quantity) { -3 }
45
+ it { is_expected.to_not be_valid }
46
+ end
47
+ end
48
+
49
+ describe "availability" do
50
+ let(:stock_item) do
51
+ transfer_item.variant.stock_items.find_by(stock_location: stock_transfer.source_location)
52
+ end
53
+ let(:expected_quantity) { 1 }
54
+ let(:received_quantity) { 1 }
55
+
56
+ subject { transfer_item.valid? }
57
+
58
+ shared_examples_for 'availability check fails' do
59
+ it "validates the availability" do
60
+ subject
61
+ expect(transfer_item.errors.full_messages).to include Spree.t('errors.messages.transfer_item_insufficient_stock')
62
+ end
63
+ end
64
+
65
+ shared_examples_for 'availability check passes' do
66
+ it "doesn't validate the availability" do
67
+ subject
68
+ expect(transfer_item.errors.full_messages).to_not include Spree.t('errors.messages.transfer_item_insufficient_stock')
69
+ end
70
+ end
71
+
72
+ context "transfer order is closed" do
73
+ before do
74
+ stock_transfer.update_attributes!(closed_at: Time.now)
75
+ end
76
+
77
+ context "variant is not available" do
78
+ before do
79
+ stock_item.set_count_on_hand(0)
80
+ end
81
+ include_examples 'availability check passes'
82
+
83
+ context "stock location doesn't check stock" do
84
+ before do
85
+ stock_location.update_attributes!(check_stock_on_transfer: false)
86
+ end
87
+ include_examples 'availability check passes'
88
+ end
89
+ end
90
+
91
+ context "variant available" do
92
+ before do
93
+ stock_item.set_count_on_hand(transfer_item.expected_quantity)
94
+ end
95
+ include_examples 'availability check passes'
96
+ end
97
+
98
+ context "variant does not exist in stock location" do
99
+ before do
100
+ stock_item.destroy
101
+ end
102
+ include_examples 'availability check passes'
103
+ end
104
+ end
105
+
106
+ context "transfer order isn't closed" do
107
+ before do
108
+ stock_transfer.update_attributes!(closed_at: nil)
109
+ end
110
+
111
+ context "variant is not available" do
112
+ before do
113
+ stock_item.set_count_on_hand(0)
114
+ end
115
+ include_examples 'availability check fails'
116
+
117
+ context "stock location doesn't check stock" do
118
+ before do
119
+ stock_location.update_attributes!(check_stock_on_transfer: false)
120
+ end
121
+ include_examples 'availability check passes'
122
+ end
123
+ end
124
+
125
+ context "variant available" do
126
+ before do
127
+ stock_item.set_count_on_hand(transfer_item.expected_quantity)
128
+ end
129
+ include_examples 'availability check passes'
130
+ end
131
+
132
+ context "variant does not exist in stock location" do
133
+ before do
134
+ stock_item.destroy
135
+ end
136
+ include_examples 'availability check fails'
137
+ end
138
+ end
139
+ end
140
+ end
141
+
142
+ describe "received stock transfer guard" do
143
+ subject { transfer_item.reload.update_attributes(received_quantity: 2) }
144
+
145
+ describe "closed stock transfer" do
146
+ context "stock_transfer is not closed" do
147
+ before do
148
+ stock_transfer.update_attributes!(closed_at: nil)
149
+ end
150
+
151
+ it { is_expected.to eq true }
152
+ end
153
+
154
+ context "stock_transfer is closed" do
155
+ before do
156
+ stock_transfer.update_attributes!(closed_at: Time.now)
157
+ end
158
+
159
+ it { is_expected.to eq false }
160
+
161
+ it "adds an error message" do
162
+ subject
163
+ expect(transfer_item.errors.full_messages).to include Spree.t('errors.messages.cannot_modify_transfer_item_closed_stock_transfer')
164
+ end
165
+ end
166
+ end
167
+ end
168
+
169
+ describe "expected quantity update guard" do
170
+ let(:attrs) { { expected_quantity: 1 } }
171
+
172
+ subject { transfer_item.update_attributes(attrs) }
173
+
174
+ context "stock transfer is finalized" do
175
+ before do
176
+ stock_transfer.update_attributes(finalized_at: Time.now)
177
+ end
178
+
179
+ it "adds an error message" do
180
+ subject
181
+ expect(transfer_item.errors.full_messages).to include Spree.t('errors.messages.cannot_update_expected_transfer_item_with_finalized_stock_transfer')
182
+ end
183
+
184
+ context "updating received_quantity" do
185
+ let(:attrs) { { received_quantity: 1 } }
186
+
187
+ it "updates the received quantity successfully" do
188
+ expect { subject }.to change { transfer_item.received_quantity }.to(1)
189
+ end
190
+ end
191
+ end
192
+
193
+ context "stock transfer is not finalized" do
194
+ before do
195
+ stock_transfer.update_attributes(finalized_at: nil, shipped_at: nil)
196
+ end
197
+
198
+ it "updates the expected quantity successfully" do
199
+ expect { subject }.to change { transfer_item.expected_quantity }.to(1)
200
+ end
201
+ end
202
+ end
203
+
204
+ describe "destroy finalized stock transfer guard" do
205
+ subject { transfer_item.destroy }
206
+
207
+ context "stock transfer is finalized" do
208
+ before do
209
+ stock_transfer.update_attributes(finalized_at: Time.now)
210
+ end
211
+
212
+ it "does not destroy the transfer item" do
213
+ expect { subject }.to_not change { Spree::TransferItem.count }
214
+ end
215
+
216
+ it "adds an error message" do
217
+ subject
218
+ expect(transfer_item.errors.full_messages).to include Spree.t('errors.messages.cannot_delete_transfer_item_with_finalized_stock_transfer')
219
+ end
220
+ end
221
+
222
+ context "stock transfer is not finalized" do
223
+ before do
224
+ stock_transfer.update_attributes(finalized_at: nil, shipped_at: nil)
225
+ end
226
+
227
+ it "destroys the transfer item" do
228
+ expect { subject }.to change { Spree::TransferItem.count }.by(-1)
229
+ end
230
+ end
231
+
232
+ context "scopes" do
233
+ let(:partially_received) { stock_transfer.transfer_items.first }
234
+ let(:fully_received) { stock_transfer.transfer_items.last }
235
+ let(:variant) { create(:variant)}
236
+
237
+ before do
238
+ fully_received.update_attributes(expected_quantity: 1, received_quantity: 1)
239
+ partially_received.update_attributes(expected_quantity: 2, received_quantity: 1)
240
+
241
+ stock_transfer.source_location.stock_item(variant).set_count_on_hand(5)
242
+ stock_transfer.transfer_items.create!(variant: variant, expected_quantity: 1, received_quantity: 0)
243
+ end
244
+
245
+ context '.received' do
246
+ it 'only returns items that have received quantity greater than 0' do
247
+ expect(Spree::TransferItem.received).to match_array [fully_received, partially_received]
248
+ end
249
+ end
250
+
251
+ context '.fully_received' do
252
+ it 'returns only items that have not been fully received' do
253
+ expect(Spree::TransferItem.fully_received).to eq [fully_received]
254
+ end
255
+ end
256
+
257
+ context '.partially_received' do
258
+ it 'returns only items where received quantity is less that expected' do
259
+ expect(Spree::TransferItem.partially_received).to eq [partially_received]
260
+ end
261
+ end
262
+ end
263
+ end
264
+ end
@@ -0,0 +1,148 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::UnitCancel do
4
+ let(:unit_cancel) { Spree::UnitCancel.create!(inventory_unit: inventory_unit, reason: Spree::UnitCancel::SHORT_SHIP) }
5
+ let(:inventory_unit) { create(:inventory_unit) }
6
+
7
+ describe '#adjust!' do
8
+ subject { unit_cancel.adjust! }
9
+
10
+ it "creates an adjustment with the correct attributes" do
11
+ expect { subject }.to change{ Spree::Adjustment.count }.by(1)
12
+
13
+ adjustment = Spree::Adjustment.last
14
+ expect(adjustment.adjustable).to eq inventory_unit.line_item
15
+ expect(adjustment.amount).to eq -10.0
16
+ expect(adjustment.order).to eq inventory_unit.order
17
+ expect(adjustment.label).to eq "Cancellation - Short Ship"
18
+ expect(adjustment.eligible).to eq true
19
+ expect(adjustment.state).to eq 'closed'
20
+ end
21
+
22
+ context "when an adjustment has already been created" do
23
+ before { unit_cancel.adjust! }
24
+
25
+ it "raises" do
26
+ expect { subject }.to raise_error("Adjustment is already created")
27
+ end
28
+ end
29
+ end
30
+
31
+ describe '#compute_amount' do
32
+ subject { unit_cancel.compute_amount(line_item) }
33
+
34
+ let(:line_item) { inventory_unit.line_item }
35
+ let!(:inventory_unit2) { create(:inventory_unit, line_item: inventory_unit.line_item) }
36
+
37
+ context "all inventory on the line item are not canceled" do
38
+ it "divides the line item total by the inventory units size" do
39
+ expect(subject).to eq -5.0
40
+ end
41
+ end
42
+
43
+ context "some inventory on the line item is canceled" do
44
+ before { inventory_unit2.cancel! }
45
+
46
+ it "divides the line item total by the uncanceled units size" do
47
+ expect(subject).to eq -10.0
48
+ end
49
+ end
50
+
51
+ context "it is called with a line item that doesnt belong to the inventory unit" do
52
+ let(:line_item) { create(:line_item) }
53
+
54
+ it "raises an error" do
55
+ expect { subject }.to raise_error RuntimeError
56
+ end
57
+ end
58
+
59
+ context "when exchanges are present" do
60
+ let!(:order) { create(:order, ship_address: create(:address)) }
61
+ let!(:product) { create(:product, price: 10.00) }
62
+ let!(:variant) do
63
+ create(:variant, price: 10, product: product, track_inventory: false)
64
+ end
65
+ let!(:shipping_method) { create(:free_shipping_method) }
66
+ let(:exchange_variant) do
67
+ create(:variant, product: variant.product, price: 10, track_inventory: false)
68
+ end
69
+
70
+ before do
71
+ @old_expedited_exchanges_value = Spree::Config[:expedited_exchanges]
72
+ Spree::Config[:expedited_exchanges] = true
73
+ end
74
+ after do
75
+ Spree::Config[:expedited_exchanges] = @old_expedited_exchanges_value
76
+ end
77
+
78
+ # This sets up an order with one shipped inventory unit, one unshipped
79
+ # inventory unit, and one unshipped exchange inventory unit.
80
+ before do
81
+ # Complete an order with 1 line item with quantity=2
82
+ order.contents.add(variant, 2)
83
+ order.contents.advance
84
+ create(:payment, order: order, amount: order.total)
85
+ order.payments.reload
86
+ order.complete!
87
+ order.reload
88
+
89
+ # Ship _one_ of the inventory units
90
+ @shipment = order.shipments.first
91
+ @shipped_inventory_unit = order.inventory_units[0]
92
+ @unshipped_inventory_unit = order.inventory_units[1]
93
+ order.shipping.ship(
94
+ inventory_units: [@shipped_inventory_unit],
95
+ stock_location: @shipment.stock_location,
96
+ address: order.ship_address,
97
+ shipping_method: @shipment.shipping_method,
98
+ )
99
+
100
+ # Create an expedited exchange for the shipped inventory unit.
101
+ # This generates a new inventory unit attached to the existing line item.
102
+ Spree::ReturnAuthorization.create!(
103
+ order: order,
104
+ stock_location: @shipment.stock_location,
105
+ reason: create(:return_reason),
106
+ return_items: [
107
+ Spree::ReturnItem.new(
108
+ inventory_unit: @shipped_inventory_unit,
109
+ exchange_variant: exchange_variant,
110
+ ),
111
+ ],
112
+ )
113
+ @exchange_inventory_unit = order.inventory_units.reload[2]
114
+ end
115
+
116
+ context 'when canceling an unshipped inventory unit from the original order' do
117
+ subject do
118
+ unit_cancel.compute_amount(@unshipped_inventory_unit.line_item)
119
+ end
120
+
121
+ let(:unit_cancel) do
122
+ Spree::UnitCancel.create!(
123
+ inventory_unit: @unshipped_inventory_unit,
124
+ reason: Spree::UnitCancel::SHORT_SHIP,
125
+ )
126
+ end
127
+
128
+ it { is_expected.to eq(-10.00) }
129
+ end
130
+
131
+ context 'when canceling an unshipped exchange inventory unit' do
132
+ subject do
133
+ unit_cancel.compute_amount(@exchange_inventory_unit.line_item)
134
+ end
135
+
136
+ let(:unit_cancel) do
137
+ Spree::UnitCancel.create!(
138
+ inventory_unit: @exchange_inventory_unit,
139
+ reason: Spree::UnitCancel::SHORT_SHIP,
140
+ )
141
+ end
142
+
143
+ it { is_expected.to eq(-10.00) }
144
+ end
145
+ end
146
+ end
147
+
148
+ end