spree_core 3.0.5 → 3.0.6

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