solidus_core 1.0.2 → 1.0.3

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 (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