spree_core 3.0.5 → 3.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (194) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/Gemfile +3 -0
  4. data/Rakefile +30 -0
  5. data/app/assets/javascripts/spree.js.coffee.erb +1 -1
  6. data/app/models/spree/ability.rb +1 -1
  7. data/app/models/spree/base.rb +3 -1
  8. data/app/models/spree/order_updater.rb +2 -1
  9. data/app/models/spree/price.rb +7 -12
  10. data/app/models/spree/product.rb +3 -2
  11. data/app/models/spree/reimbursement.rb +1 -1
  12. data/app/models/spree/state.rb +2 -0
  13. data/app/models/spree/zone.rb +1 -1
  14. data/lib/spree/core/version.rb +1 -1
  15. data/lib/spree/testing_support/shoulda_matcher_configuration.rb +6 -0
  16. data/script/rails +9 -0
  17. data/spec/fixtures/thinking-cat.jpg +0 -0
  18. data/spec/helpers/base_helper_spec.rb +137 -0
  19. data/spec/helpers/products_helper_spec.rb +224 -0
  20. data/spec/lib/calculated_adjustments_spec.rb +7 -0
  21. data/spec/lib/i18n_spec.rb +123 -0
  22. data/spec/lib/search/base_spec.rb +86 -0
  23. data/spec/lib/spree/core/controller_helpers/auth_spec.rb +101 -0
  24. data/spec/lib/spree/core/controller_helpers/order_spec.rb +95 -0
  25. data/spec/lib/spree/core/controller_helpers/search_spec.rb +17 -0
  26. data/spec/lib/spree/core/controller_helpers/store_spec.rb +16 -0
  27. data/spec/lib/spree/core/controller_helpers/strong_parameters_spec.rb +39 -0
  28. data/spec/lib/spree/core/delegate_belongs_to_spec.rb +22 -0
  29. data/spec/lib/spree/core/importer/order_spec.rb +502 -0
  30. data/spec/lib/spree/core/validators/email_spec.rb +53 -0
  31. data/spec/lib/spree/localized_number_spec.rb +38 -0
  32. data/spec/lib/spree/migrations_spec.rb +34 -0
  33. data/spec/lib/spree/money_spec.rb +122 -0
  34. data/spec/lib/tasks/exchanges_spec.rb +136 -0
  35. data/spec/mailers/order_mailer_spec.rb +124 -0
  36. data/spec/mailers/reimbursement_mailer_spec.rb +47 -0
  37. data/spec/mailers/shipment_mailer_spec.rb +63 -0
  38. data/spec/mailers/test_mailer_spec.rb +24 -0
  39. data/spec/models/spree/ability_spec.rb +246 -0
  40. data/spec/models/spree/address_spec.rb +291 -0
  41. data/spec/models/spree/adjustable/adjustments_updater_spec.rb +286 -0
  42. data/spec/models/spree/adjustment_spec.rb +163 -0
  43. data/spec/models/spree/app_configuration_spec.rb +23 -0
  44. data/spec/models/spree/asset_spec.rb +25 -0
  45. data/spec/models/spree/calculator/default_tax_spec.rb +127 -0
  46. data/spec/models/spree/calculator/flat_percent_item_total_spec.rb +25 -0
  47. data/spec/models/spree/calculator/flat_rate_spec.rb +47 -0
  48. data/spec/models/spree/calculator/flexi_rate_spec.rb +41 -0
  49. data/spec/models/spree/calculator/percent_on_line_item_spec.rb +15 -0
  50. data/spec/models/spree/calculator/price_sack_spec.rb +30 -0
  51. data/spec/models/spree/calculator/refunds/default_refund_amount_spec.rb +51 -0
  52. data/spec/models/spree/calculator/shipping.rb +8 -0
  53. data/spec/models/spree/calculator/shipping/flat_percent_item_total_spec.rb +23 -0
  54. data/spec/models/spree/calculator/shipping/flat_rate_spec.rb +13 -0
  55. data/spec/models/spree/calculator/shipping/flexi_rate_spec.rb +52 -0
  56. data/spec/models/spree/calculator/shipping/per_item_spec.rb +20 -0
  57. data/spec/models/spree/calculator/shipping/price_sack_spec.rb +29 -0
  58. data/spec/models/spree/calculator/tiered_flat_rate_spec.rb +40 -0
  59. data/spec/models/spree/calculator/tiered_percent_spec.rb +51 -0
  60. data/spec/models/spree/calculator_spec.rb +69 -0
  61. data/spec/models/spree/classification_spec.rb +93 -0
  62. data/spec/models/spree/concerns/display_money_spec.rb +43 -0
  63. data/spec/models/spree/country_spec.rb +18 -0
  64. data/spec/models/spree/credit_card_spec.rb +324 -0
  65. data/spec/models/spree/customer_return_spec.rb +262 -0
  66. data/spec/models/spree/exchange_spec.rb +75 -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 +54 -0
  70. data/spec/models/spree/image_spec.rb +5 -0
  71. data/spec/models/spree/inventory_unit_spec.rb +242 -0
  72. data/spec/models/spree/line_item_spec.rb +267 -0
  73. data/spec/models/spree/option_type_spec.rb +14 -0
  74. data/spec/models/spree/option_value_spec.rb +13 -0
  75. data/spec/models/spree/order/address_spec.rb +50 -0
  76. data/spec/models/spree/order/adjustments_spec.rb +29 -0
  77. data/spec/models/spree/order/callbacks_spec.rb +42 -0
  78. data/spec/models/spree/order/checkout_spec.rb +764 -0
  79. data/spec/models/spree/order/currency_updater_spec.rb +32 -0
  80. data/spec/models/spree/order/finalizing_spec.rb +117 -0
  81. data/spec/models/spree/order/helpers_spec.rb +5 -0
  82. data/spec/models/spree/order/payment_spec.rb +214 -0
  83. data/spec/models/spree/order/risk_assessment_spec.rb +84 -0
  84. data/spec/models/spree/order/shipments_spec.rb +43 -0
  85. data/spec/models/spree/order/state_machine_spec.rb +216 -0
  86. data/spec/models/spree/order/tax_spec.rb +84 -0
  87. data/spec/models/spree/order/totals_spec.rb +24 -0
  88. data/spec/models/spree/order/updating_spec.rb +18 -0
  89. data/spec/models/spree/order/validations_spec.rb +15 -0
  90. data/spec/models/spree/order_contents_spec.rb +256 -0
  91. data/spec/models/spree/order_inventory_spec.rb +228 -0
  92. data/spec/models/spree/order_merger_spec.rb +133 -0
  93. data/spec/models/spree/order_spec.rb +954 -0
  94. data/spec/models/spree/order_updater_spec.rb +283 -0
  95. data/spec/models/spree/payment/gateway_options_spec.rb +119 -0
  96. data/spec/models/spree/payment_method_spec.rb +95 -0
  97. data/spec/models/spree/payment_spec.rb +926 -0
  98. data/spec/models/spree/preference_spec.rb +80 -0
  99. data/spec/models/spree/preferences/configuration_spec.rb +30 -0
  100. data/spec/models/spree/preferences/preferable_spec.rb +348 -0
  101. data/spec/models/spree/preferences/scoped_store_spec.rb +58 -0
  102. data/spec/models/spree/preferences/store_spec.rb +46 -0
  103. data/spec/models/spree/price_spec.rb +42 -0
  104. data/spec/models/spree/product/scopes_spec.rb +148 -0
  105. data/spec/models/spree/product_duplicator_spec.rb +103 -0
  106. data/spec/models/spree/product_filter_spec.rb +26 -0
  107. data/spec/models/spree/product_option_type_spec.rb +5 -0
  108. data/spec/models/spree/product_property_spec.rb +11 -0
  109. data/spec/models/spree/product_spec.rb +474 -0
  110. data/spec/models/spree/promotion/actions/create_adjustment_spec.rb +50 -0
  111. data/spec/models/spree/promotion/actions/create_item_adjustments_spec.rb +148 -0
  112. data/spec/models/spree/promotion/actions/create_line_items_spec.rb +86 -0
  113. data/spec/models/spree/promotion/actions/free_shipping_spec.rb +36 -0
  114. data/spec/models/spree/promotion/rules/first_order_spec.rb +75 -0
  115. data/spec/models/spree/promotion/rules/item_total_spec.rb +282 -0
  116. data/spec/models/spree/promotion/rules/one_use_per_user_spec.rb +42 -0
  117. data/spec/models/spree/promotion/rules/option_value_spec.rb +90 -0
  118. data/spec/models/spree/promotion/rules/product_spec.rb +143 -0
  119. data/spec/models/spree/promotion/rules/taxon_spec.rb +102 -0
  120. data/spec/models/spree/promotion/rules/user_logged_in_spec.rb +27 -0
  121. data/spec/models/spree/promotion/rules/user_spec.rb +37 -0
  122. data/spec/models/spree/promotion_action_spec.rb +10 -0
  123. data/spec/models/spree/promotion_category_spec.rb +17 -0
  124. data/spec/models/spree/promotion_handler/cart_spec.rb +102 -0
  125. data/spec/models/spree/promotion_handler/coupon_spec.rb +323 -0
  126. data/spec/models/spree/promotion_handler/free_shipping_spec.rb +48 -0
  127. data/spec/models/spree/promotion_handler/page_spec.rb +44 -0
  128. data/spec/models/spree/promotion_rule_spec.rb +29 -0
  129. data/spec/models/spree/promotion_spec.rb +603 -0
  130. data/spec/models/spree/property_spec.rb +5 -0
  131. data/spec/models/spree/prototype_spec.rb +5 -0
  132. data/spec/models/spree/refund_spec.rb +195 -0
  133. data/spec/models/spree/reimbursement/credit_spec.rb +36 -0
  134. data/spec/models/spree/reimbursement/reimbursement_type_engine_spec.rb +140 -0
  135. data/spec/models/spree/reimbursement/reimbursement_type_validator_spec.rb +83 -0
  136. data/spec/models/spree/reimbursement_performer_spec.rb +30 -0
  137. data/spec/models/spree/reimbursement_spec.rb +215 -0
  138. data/spec/models/spree/reimbursement_tax_calculator_spec.rb +51 -0
  139. data/spec/models/spree/reimbursement_type/credit_spec.rb +53 -0
  140. data/spec/models/spree/reimbursement_type/exchange_spec.rb +46 -0
  141. data/spec/models/spree/reimbursement_type/original_payment_spec.rb +55 -0
  142. data/spec/models/spree/return_authorization_spec.rb +250 -0
  143. data/spec/models/spree/return_item/eligibility_validator/default_spec.rb +77 -0
  144. data/spec/models/spree/return_item/eligibility_validator/inventory_shipped_spec.rb +58 -0
  145. data/spec/models/spree/return_item/eligibility_validator/no_reimbursements_spec.rb +61 -0
  146. data/spec/models/spree/return_item/eligibility_validator/order_completed_spec.rb +32 -0
  147. data/spec/models/spree/return_item/eligibility_validator/rma_required_spec.rb +29 -0
  148. data/spec/models/spree/return_item/eligibility_validator/time_since_purchase_spec.rb +35 -0
  149. data/spec/models/spree/return_item/exchange_variant_eligibility/same_option_value_spec.rb +65 -0
  150. data/spec/models/spree/return_item/exchange_variant_eligibility/same_product_spec.rb +43 -0
  151. data/spec/models/spree/return_item_spec.rb +682 -0
  152. data/spec/models/spree/returns_calculator_spec.rb +14 -0
  153. data/spec/models/spree/shipment_spec.rb +740 -0
  154. data/spec/models/spree/shipping_calculator_spec.rb +45 -0
  155. data/spec/models/spree/shipping_category_spec.rb +5 -0
  156. data/spec/models/spree/shipping_method_spec.rb +88 -0
  157. data/spec/models/spree/shipping_rate_spec.rb +141 -0
  158. data/spec/models/spree/state_spec.rb +18 -0
  159. data/spec/models/spree/stock/availability_validator_spec.rb +36 -0
  160. data/spec/models/spree/stock/content_item_spec.rb +22 -0
  161. data/spec/models/spree/stock/coordinator_spec.rb +51 -0
  162. data/spec/models/spree/stock/differentiator_spec.rb +39 -0
  163. data/spec/models/spree/stock/estimator_spec.rb +154 -0
  164. data/spec/models/spree/stock/inventory_unit_builder_spec.rb +38 -0
  165. data/spec/models/spree/stock/package_spec.rb +194 -0
  166. data/spec/models/spree/stock/packer_spec.rb +70 -0
  167. data/spec/models/spree/stock/prioritizer_spec.rb +125 -0
  168. data/spec/models/spree/stock/quantifier_spec.rb +97 -0
  169. data/spec/models/spree/stock/splitter/backordered_spec.rb +29 -0
  170. data/spec/models/spree/stock/splitter/base_spec.rb +21 -0
  171. data/spec/models/spree/stock/splitter/shipping_category_spec.rb +47 -0
  172. data/spec/models/spree/stock/splitter/weight_spec.rb +32 -0
  173. data/spec/models/spree/stock_item_spec.rb +410 -0
  174. data/spec/models/spree/stock_location_spec.rb +243 -0
  175. data/spec/models/spree/stock_movement_spec.rb +56 -0
  176. data/spec/models/spree/stock_transfer_spec.rb +50 -0
  177. data/spec/models/spree/store_spec.rb +50 -0
  178. data/spec/models/spree/tax_category_spec.rb +27 -0
  179. data/spec/models/spree/tax_rate_spec.rb +382 -0
  180. data/spec/models/spree/taxon_spec.rb +74 -0
  181. data/spec/models/spree/taxonomy_spec.rb +18 -0
  182. data/spec/models/spree/tracker_spec.rb +21 -0
  183. data/spec/models/spree/user_spec.rb +130 -0
  184. data/spec/models/spree/validations/db_maximum_length_validator_spec.rb +24 -0
  185. data/spec/models/spree/variant_spec.rb +523 -0
  186. data/spec/models/spree/zone_spec.rb +444 -0
  187. data/spec/spec_helper.rb +74 -0
  188. data/spec/support/big_decimal.rb +5 -0
  189. data/spec/support/concerns/adjustment_source_spec.rb +23 -0
  190. data/spec/support/concerns/default_price_spec.rb +28 -0
  191. data/spec/support/rake.rb +13 -0
  192. data/spec/support/test_gateway.rb +2 -0
  193. data/spree_core.gemspec +48 -0
  194. metadata +185 -4
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ class FakesController < ApplicationController
4
+ include Spree::Core::ControllerHelpers::StrongParameters
5
+ end
6
+
7
+ describe Spree::Core::ControllerHelpers::StrongParameters, type: :controller do
8
+ controller(FakesController) {}
9
+
10
+ describe '#permitted_attributes' do
11
+ it 'returns Spree::PermittedAttributes module' do
12
+ expect(controller.permitted_attributes).to eq Spree::PermittedAttributes
13
+ end
14
+ end
15
+
16
+ describe '#permitted_payment_attributes' do
17
+ it 'returns Array class' do
18
+ expect(controller.permitted_payment_attributes.class).to eq Array
19
+ end
20
+ end
21
+
22
+ describe '#permitted_checkout_attributes' do
23
+ it 'returns Array class' do
24
+ expect(controller.permitted_checkout_attributes.class).to eq Array
25
+ end
26
+ end
27
+
28
+ describe '#permitted_order_attributes' do
29
+ it 'returns Array class' do
30
+ expect(controller.permitted_order_attributes.class).to eq Array
31
+ end
32
+ end
33
+
34
+ describe '#permitted_product_attributes' do
35
+ it 'returns Array class' do
36
+ expect(controller.permitted_product_attributes.class).to eq Array
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ # This is a bit of a insane spec I have to admit
4
+ # Chosed the spree_payment_methods table because it has a `name` column
5
+ # already. Stubs wouldn't work here (the delegation runs before this spec is
6
+ # loaded) and adding a column here might make the test even crazy so here we go
7
+ module Spree
8
+ class DelegateBelongsToStubModel < Spree::Base
9
+ self.table_name = "spree_payment_methods"
10
+ belongs_to :product
11
+ delegate_belongs_to :product, :name
12
+ end
13
+
14
+ describe DelegateBelongsToStubModel do
15
+ context "model has column attr delegated to associated object" do
16
+ it "doesnt touch the associated object" do
17
+ expect(subject).not_to receive(:product)
18
+ subject.name
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,502 @@
1
+ require 'spec_helper'
2
+
3
+ module Spree
4
+ module Core
5
+ describe Importer::Order do
6
+
7
+ let!(:country) { create(:country) }
8
+ let!(:state) { country.states.first || create(:state, :country => country) }
9
+ let!(:stock_location) { create(:stock_location, admin_name: 'Admin Name') }
10
+
11
+ let(:user) { stub_model(LegacyUser, :email => 'fox@mudler.com') }
12
+ let(:shipping_method) { create(:shipping_method) }
13
+ let(:payment_method) { create(:check_payment_method) }
14
+
15
+ let(:product) { product = Spree::Product.create(:name => 'Test',
16
+ :sku => 'TEST-1',
17
+ :price => 33.22)
18
+ product.shipping_category = create(:shipping_category)
19
+ product.save
20
+ product }
21
+
22
+ let(:variant) { variant = product.master
23
+ variant.stock_items.each { |si| si.update_attribute(:count_on_hand, 10) }
24
+ variant }
25
+
26
+ let(:sku) { variant.sku }
27
+ let(:variant_id) { variant.id }
28
+
29
+ let(:line_items) { [{ variant_id: variant.id, quantity: 5 }] }
30
+ let(:ship_address) {{
31
+ :address1 => '123 Testable Way',
32
+ :firstname => 'Fox',
33
+ :lastname => 'Mulder',
34
+ :city => 'Washington',
35
+ :country_id => country.id,
36
+ :state_id => state.id,
37
+ :zipcode => '66666',
38
+ :phone => '666-666-6666'
39
+ }}
40
+
41
+ it 'can import an order number' do
42
+ params = { number: '123-456-789' }
43
+ order = Importer::Order.import(user, params)
44
+ expect(order.number).to eq '123-456-789'
45
+ end
46
+
47
+ it 'optionally add completed at' do
48
+ params = { email: 'test@test.com',
49
+ completed_at: Time.now,
50
+ line_items_attributes: line_items }
51
+
52
+ order = Importer::Order.import(user, params)
53
+ expect(order).to be_completed
54
+ expect(order.state).to eq 'complete'
55
+ end
56
+
57
+ it "assigns order[email] over user email to order" do
58
+ params = { email: 'wooowww@test.com' }
59
+ order = Importer::Order.import(user, params)
60
+ expect(order.email).to eq params[:email]
61
+ end
62
+
63
+ context "assigning a user to an order" do
64
+ let(:other_user) { stub_model(LegacyUser, :email => 'dana@scully.com') }
65
+
66
+ context "as an admin" do
67
+ before { allow(user).to receive_messages :has_spree_role? => true }
68
+
69
+ context "a user's id is not provided" do
70
+ # this is a regression spec for an issue we ran into at Bonobos
71
+ it "doesn't unassociate the admin from the order" do
72
+ params = { }
73
+ order = Importer::Order.import(user, params)
74
+ expect(order.user_id).to eq(user.id)
75
+ end
76
+ end
77
+ end
78
+
79
+ context "as a user" do
80
+ before { allow(user).to receive_messages :has_spree_role? => false }
81
+ it "does not assign the order to the other user" do
82
+ params = { user_id: other_user.id }
83
+ order = Importer::Order.import(user, params)
84
+ expect(order.user_id).to eq(user.id)
85
+ end
86
+ end
87
+ end
88
+
89
+ it 'can build an order from API with just line items' do
90
+ params = { :line_items_attributes => line_items }
91
+
92
+ expect(Importer::Order).to receive(:ensure_variant_id_from_params).and_return({variant_id: variant.id, quantity: 5})
93
+ order = Importer::Order.import(user, params)
94
+ expect(order.user).to eq(nil)
95
+ line_item = order.line_items.first
96
+ expect(line_item.quantity).to eq(5)
97
+ expect(line_item.variant_id).to eq(variant_id)
98
+ end
99
+
100
+ it 'handles line_item building exceptions' do
101
+ line_items.first[:variant_id] = 'XXX'
102
+ params = { line_items_attributes: line_items }
103
+
104
+ expect {
105
+ Importer::Order.import(user, params)
106
+ }.to raise_error /XXX/
107
+ end
108
+
109
+ it 'handles line_item updating exceptions' do
110
+ line_items.first[:currency] = 'GBP'
111
+ params = { line_items_attributes: line_items }
112
+
113
+ expect {
114
+ Importer::Order.import(user, params)
115
+ }.to raise_error /Validation failed/
116
+ end
117
+
118
+ it 'can build an order from API with variant sku' do
119
+ params = { line_items_attributes: [{ sku: sku, quantity: 5 }] }
120
+
121
+ order = Importer::Order.import(user, params)
122
+
123
+ line_item = order.line_items.first
124
+ expect(line_item.variant_id).to eq(variant_id)
125
+ expect(line_item.quantity).to eq(5)
126
+ end
127
+
128
+ it 'handles exceptions when sku is not found' do
129
+ params = { line_items_attributes: [{ sku: 'XXX', quantity: 5 }] }
130
+ expect {
131
+ Importer::Order.import(user, params)
132
+ }.to raise_error /XXX/
133
+ end
134
+
135
+ it 'can build an order from API shipping address' do
136
+ params = { :ship_address_attributes => ship_address,
137
+ :line_items_attributes => line_items }
138
+
139
+ order = Importer::Order.import(user, params)
140
+ expect(order.ship_address.address1).to eq '123 Testable Way'
141
+ end
142
+
143
+ it 'can build an order from API with country attributes' do
144
+ ship_address.delete(:country_id)
145
+ ship_address[:country] = { 'iso' => 'US' }
146
+ params = { :ship_address_attributes => ship_address,
147
+ :line_items_attributes => line_items }
148
+
149
+ order = Importer::Order.import(user, params)
150
+ expect(order.ship_address.country.iso).to eq 'US'
151
+ end
152
+
153
+ it 'handles country lookup exceptions' do
154
+ ship_address.delete(:country_id)
155
+ ship_address[:country] = { 'iso' => 'XXX' }
156
+ params = { ship_address_attributes: ship_address,
157
+ line_items_attributes: line_items }
158
+
159
+ expect {
160
+ Importer::Order.import(user, params)
161
+ }.to raise_error /XXX/
162
+ end
163
+
164
+ it 'can build an order from API with state attributes' do
165
+ ship_address.delete(:state_id)
166
+ ship_address[:state] = { 'name' => state.name }
167
+ params = {
168
+ ship_address_attributes: ship_address,
169
+ line_items_attributes: line_items
170
+ }
171
+
172
+ order = Importer::Order.import(user, params)
173
+ expect(order.ship_address.state.name).to eq 'Alabama'
174
+ end
175
+
176
+ context "with a different currency" do
177
+ before { variant.price_in("GBP").update_attribute(:price, 18.99) }
178
+
179
+ it "sets the order currency" do
180
+ params = {
181
+ currency: "GBP"
182
+ }
183
+ order = Importer::Order.import(user, params)
184
+ expect(order.currency).to eq "GBP"
185
+ end
186
+
187
+ it "can handle it when a line order price is specified" do
188
+ params = {
189
+ currency: "GBP",
190
+ line_items_attributes: line_items
191
+ }
192
+ line_items.first.merge! currency: "GBP", price: 1.99
193
+ order = Importer::Order.import(user, params)
194
+ expect(order.currency).to eq "GBP"
195
+ expect(order.line_items.first.price).to eq 1.99
196
+ expect(order.line_items.first.currency).to eq "GBP"
197
+ end
198
+ end
199
+
200
+ context "state passed is not associated with country" do
201
+ let(:params) do
202
+ {
203
+ ship_address_attributes: ship_address,
204
+ line_items_attributes: line_items
205
+ }
206
+ end
207
+
208
+ let(:other_state) { create(:state, name: "Uhuhuh", country: create(:country)) }
209
+
210
+ before do
211
+ ship_address.delete(:state_id)
212
+ ship_address[:state] = { 'name' => other_state.name }
213
+ end
214
+
215
+ it 'sets states name instead of state id' do
216
+ order = Importer::Order.import(user, params)
217
+ expect(order.ship_address.state_name).to eq other_state.name
218
+ end
219
+ end
220
+
221
+ it 'sets state name if state record not found' do
222
+ ship_address.delete(:state_id)
223
+ ship_address[:state] = { 'name' => 'XXX' }
224
+ params = { :ship_address_attributes => ship_address,
225
+ :line_items_attributes => line_items }
226
+
227
+ order = Importer::Order.import(user, params)
228
+ expect(order.ship_address.state_name).to eq 'XXX'
229
+ end
230
+
231
+ context 'variant not deleted' do
232
+ it 'ensures variant id from api' do
233
+ hash = { sku: variant.sku }
234
+ Importer::Order.ensure_variant_id_from_params(hash)
235
+ expect(hash[:variant_id]).to eq variant.id
236
+ end
237
+ end
238
+
239
+ context 'variant was deleted' do
240
+ it 'raise error as variant shouldnt be found' do
241
+ variant.product.destroy
242
+ hash = { sku: variant.sku }
243
+ expect {
244
+ Importer::Order.ensure_variant_id_from_params(hash)
245
+ }.to raise_error
246
+ end
247
+ end
248
+
249
+ it 'ensures_country_id for country fields' do
250
+ [:name, :iso, :iso_name, :iso3].each do |field|
251
+ address = { country: { field => country.send(field) } }
252
+ Importer::Order.ensure_country_id_from_params(address)
253
+ expect(address[:country_id]).to eq country.id
254
+ end
255
+ end
256
+
257
+ it "raises with proper message when cant find country" do
258
+ address = { country: { "name" => "NoNoCountry" } }
259
+ expect {
260
+ Importer::Order.ensure_country_id_from_params(address)
261
+ }.to raise_error /NoNoCountry/
262
+ end
263
+
264
+ it 'ensures_state_id for state fields' do
265
+ [:name, :abbr].each do |field|
266
+ address = { country_id: country.id, state: { field => state.send(field) } }
267
+ Importer::Order.ensure_state_id_from_params(address)
268
+ expect(address[:state_id]).to eq state.id
269
+ end
270
+ end
271
+
272
+ context "shipments" do
273
+ let(:params) do
274
+ {
275
+ line_items_attributes: line_items,
276
+ shipments_attributes: [
277
+ {
278
+ tracking: '123456789',
279
+ cost: '14.99',
280
+ shipping_method: shipping_method.name,
281
+ stock_location: stock_location.name,
282
+ inventory_units: 3.times.map { { sku: sku } }
283
+ },
284
+ {
285
+ tracking: '123456789',
286
+ cost: '14.99',
287
+ shipping_method: shipping_method.name,
288
+ stock_location: stock_location.name,
289
+ inventory_units: 2.times.map { { sku: sku } }
290
+ }
291
+ ]
292
+ }
293
+ end
294
+
295
+ it 'ensures variant exists and is not deleted' do
296
+ expect(Importer::Order).to receive(:ensure_variant_id_from_params).exactly(6).times { line_items.first }
297
+ order = Importer::Order.import(user, params)
298
+ end
299
+
300
+ it 'builds them properly' do
301
+ order = Importer::Order.import(user, params)
302
+ shipment = order.shipments.first
303
+
304
+ expect(shipment.cost.to_f).to eq 14.99
305
+ expect(shipment.inventory_units.first.variant_id).to eq product.master.id
306
+ expect(shipment.tracking).to eq '123456789'
307
+ expect(shipment.shipping_rates.first.cost).to eq 14.99
308
+ expect(shipment.selected_shipping_rate).to eq(shipment.shipping_rates.first)
309
+ expect(shipment.stock_location).to eq stock_location
310
+ expect(order.shipment_total.to_f).to eq 29.98
311
+ end
312
+
313
+ it "allocates inventory units to the correct shipments" do
314
+ order = Importer::Order.import(user, params)
315
+
316
+ expect(order.inventory_units.count).to eq 5
317
+ expect(order.shipments.first.inventory_units.count).to eq 3
318
+ expect(order.shipments.last.inventory_units.count).to eq 2
319
+ end
320
+
321
+ it "accepts admin name for stock location" do
322
+ params[:shipments_attributes][0][:stock_location] = stock_location.admin_name
323
+ order = Importer::Order.import(user, params)
324
+ shipment = order.shipments.first
325
+
326
+ expect(shipment.stock_location).to eq stock_location
327
+ end
328
+
329
+ it "raises if cant find stock location" do
330
+ params[:shipments_attributes][0][:stock_location] = "doesnt exist"
331
+ expect {
332
+ Importer::Order.import(user, params)
333
+ }.to raise_error
334
+ end
335
+
336
+ context 'when completed_at and shipped_at present' do
337
+ let(:params) do
338
+ {
339
+ completed_at: 2.days.ago,
340
+ line_items_attributes: line_items,
341
+ shipments_attributes: [
342
+ { tracking: '123456789',
343
+ cost: '4.99',
344
+ shipped_at: 1.day.ago,
345
+ shipping_method: shipping_method.name,
346
+ stock_location: stock_location.name,
347
+ inventory_units: [{ sku: sku }]
348
+ }
349
+ ]
350
+ }
351
+ end
352
+
353
+ it 'builds them properly' do
354
+ order = Importer::Order.import(user, params)
355
+ shipment = order.shipments.first
356
+
357
+ expect(shipment.cost.to_f).to eq 4.99
358
+ expect(shipment.inventory_units.first.variant_id).to eq product.master.id
359
+ expect(shipment.tracking).to eq '123456789'
360
+ expect(shipment.shipped_at).to be_present
361
+ expect(shipment.shipping_rates.first.cost).to eq 4.99
362
+ expect(shipment.selected_shipping_rate).to eq(shipment.shipping_rates.first)
363
+ expect(shipment.stock_location).to eq stock_location
364
+ expect(shipment.state).to eq('shipped')
365
+ expect(shipment.inventory_units.all?(&:shipped?)).to be true
366
+ expect(order.shipment_state).to eq('shipped')
367
+ expect(order.shipment_total.to_f).to eq 4.99
368
+ end
369
+ end
370
+ end
371
+
372
+ it 'handles shipment building exceptions' do
373
+ params = { :shipments_attributes => [{ tracking: '123456789',
374
+ cost: '4.99',
375
+ shipping_method: 'XXX',
376
+ inventory_units: [{ sku: sku }]
377
+ }] }
378
+ expect { Importer::Order.import(user, params) }.to raise_error /XXX/
379
+ end
380
+
381
+ it 'adds adjustments' do
382
+ params = { adjustments_attributes: [
383
+ { label: 'Shipping Discount', amount: -4.99 },
384
+ { label: 'Promotion Discount', amount: -3.00 }]
385
+ }
386
+
387
+ order = Importer::Order.import(user, params)
388
+ expect(order.adjustments.all?(&:closed?)).to be true
389
+ expect(order.adjustments.first.label).to eq 'Shipping Discount'
390
+ expect(order.adjustments.first.amount).to eq -4.99
391
+ end
392
+
393
+ it "calculates final order total correctly" do
394
+ params = {
395
+ adjustments_attributes: [
396
+ { label: 'Promotion Discount', amount: -3.00 }
397
+ ],
398
+ line_items_attributes: [
399
+ {
400
+ variant_id: variant.id,
401
+ quantity: 5
402
+ }
403
+ ]
404
+ }
405
+
406
+ order = Importer::Order.import(user, params)
407
+ expect(order.item_total).to eq(166.1)
408
+ expect(order.total).to eq(163.1) # = item_total (166.1) - adjustment_total (3.00)
409
+ end
410
+
411
+ it 'handles adjustment building exceptions' do
412
+ params = { adjustments_attributes: [
413
+ { amount: 'XXX' },
414
+ { label: 'Promotion Discount', amount: '-3.00' }] }
415
+
416
+ expect {
417
+ Importer::Order.import(user, params)
418
+ }.to raise_error /XXX/
419
+ end
420
+
421
+ it 'builds a payment using state' do
422
+ params = { payments_attributes: [{ amount: '4.99',
423
+ payment_method: payment_method.name,
424
+ state: 'completed' }] }
425
+ order = Importer::Order.import(user, params)
426
+ expect(order.payments.first.amount).to eq 4.99
427
+ end
428
+
429
+ it 'builds a payment using status as fallback' do
430
+ params = { payments_attributes: [{ amount: '4.99',
431
+ payment_method: payment_method.name,
432
+ status: 'completed' }] }
433
+ order = Importer::Order.import(user, params)
434
+ expect(order.payments.first.amount).to eq 4.99
435
+ end
436
+
437
+ it 'handles payment building exceptions' do
438
+ params = { payments_attributes: [{ amount: '4.99',
439
+ payment_method: 'XXX' }] }
440
+ expect {
441
+ order = Importer::Order.import(user, params)
442
+ }.to raise_error /XXX/
443
+ end
444
+
445
+ it 'build a source payment using years and month' do
446
+ params = { payments_attributes: [{
447
+ amount: '4.99',
448
+ payment_method: payment_method.name,
449
+ status: 'completed',
450
+ source: {
451
+ name: 'Fox',
452
+ last_digits: "7424",
453
+ cc_type: "visa",
454
+ year: '2022',
455
+ month: "5"
456
+ }
457
+ }] }
458
+
459
+ order = Importer::Order.import(user, params)
460
+ expect(order.payments.first.source.last_digits).to eq '7424'
461
+ end
462
+
463
+ it 'handles source building exceptions when do not have years and month' do
464
+ params = { payments_attributes: [{
465
+ amount: '4.99',
466
+ payment_method: payment_method.name,
467
+ status: 'completed',
468
+ source: {
469
+ name: 'Fox',
470
+ last_digits: "7424",
471
+ cc_type: "visa"
472
+ }
473
+ }] }
474
+
475
+ expect {
476
+ order = Importer::Order.import(user, params)
477
+ }.to raise_error /Validation failed: Credit card Month is not a number, Credit card Year is not a number/
478
+ end
479
+
480
+ it 'builds a payment with an optional created_at' do
481
+ created_at = 2.days.ago
482
+ params = { payments_attributes: [{ amount: '4.99',
483
+ payment_method: payment_method.name,
484
+ state: 'completed',
485
+ created_at: created_at }] }
486
+ order = Importer::Order.import(user, params)
487
+ expect(order.payments.first.created_at).to be_within(0.1).of created_at
488
+ end
489
+
490
+ context "raises error" do
491
+ it "clears out order from db" do
492
+ params = { payments_attributes: [{ payment_method: "XXX" }] }
493
+ count = Order.count
494
+
495
+ expect { Importer::Order.import(user, params) }.to raise_error
496
+ expect(Order.count).to eq count
497
+ end
498
+ end
499
+
500
+ end
501
+ end
502
+ end