solidus_api 2.10.5 → 2.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/app/controllers/spree/api/addresses_controller.rb +1 -1
  4. data/app/controllers/spree/api/base_controller.rb +11 -3
  5. data/app/controllers/spree/api/checkouts_controller.rb +1 -11
  6. data/app/controllers/spree/api/countries_controller.rb +2 -2
  7. data/app/controllers/spree/api/credit_cards_controller.rb +2 -2
  8. data/app/controllers/spree/api/customer_returns_controller.rb +67 -0
  9. data/app/controllers/spree/api/images_controller.rb +4 -4
  10. data/app/controllers/spree/api/inventory_units_controller.rb +1 -1
  11. data/app/controllers/spree/api/option_types_controller.rb +3 -3
  12. data/app/controllers/spree/api/option_values_controller.rb +2 -2
  13. data/app/controllers/spree/api/orders_controller.rb +1 -1
  14. data/app/controllers/spree/api/payments_controller.rb +1 -1
  15. data/app/controllers/spree/api/product_properties_controller.rb +9 -14
  16. data/app/controllers/spree/api/promotions_controller.rb +3 -12
  17. data/app/controllers/spree/api/properties_controller.rb +3 -3
  18. data/app/controllers/spree/api/resource_controller.rb +2 -2
  19. data/app/controllers/spree/api/return_authorizations_controller.rb +3 -3
  20. data/app/controllers/spree/api/shipments_controller.rb +1 -1
  21. data/app/controllers/spree/api/states_controller.rb +3 -3
  22. data/app/controllers/spree/api/stock_items_controller.rb +2 -2
  23. data/app/controllers/spree/api/stock_locations_controller.rb +3 -3
  24. data/app/controllers/spree/api/stock_movements_controller.rb +3 -3
  25. data/app/controllers/spree/api/stores_controller.rb +3 -3
  26. data/app/controllers/spree/api/taxonomies_controller.rb +2 -2
  27. data/app/controllers/spree/api/taxons_controller.rb +4 -4
  28. data/app/controllers/spree/api/users_controller.rb +13 -0
  29. data/app/controllers/spree/api/variants_controller.rb +3 -3
  30. data/app/controllers/spree/api/zones_controller.rb +2 -2
  31. data/app/helpers/spree/api/api_helpers.rb +18 -5
  32. data/app/views/spree/api/customer_returns/index.json.jbuilder +6 -0
  33. data/app/views/spree/api/customer_returns/new.json.jbuilder +4 -0
  34. data/app/views/spree/api/customer_returns/show.json.jbuilder +3 -0
  35. data/app/views/spree/api/errors/could_not_transition.json.jbuilder +4 -0
  36. data/app/views/spree/api/orders/could_not_transition.json.jbuilder +5 -0
  37. data/config/locales/en.yml +2 -0
  38. data/config/routes.rb +6 -3
  39. data/lib/spree/api/testing_support/helpers.rb +1 -1
  40. data/openapi/authentication.md +9 -1
  41. data/openapi/checkout-flow.md +17 -4
  42. data/openapi/main.hub.yml +1 -1
  43. data/openapi/solidus-api.oas.yml +6753 -0
  44. data/solidus_api.gemspec +19 -19
  45. metadata +14 -114
  46. data/openapi/api.oas2.yml +0 -6108
  47. data/script/rails +0 -10
  48. data/spec/controllers/spree/api/base_controller_spec.rb +0 -118
  49. data/spec/controllers/spree/api/resource_controller_spec.rb +0 -190
  50. data/spec/features/checkout_spec.rb +0 -192
  51. data/spec/fixtures/thinking-cat.jpg +0 -0
  52. data/spec/lib/spree_api_responders_spec.rb +0 -10
  53. data/spec/models/spree/legacy_user_spec.rb +0 -103
  54. data/spec/requests/api/address_books_spec.rb +0 -240
  55. data/spec/requests/jbuilder_cache_spec.rb +0 -34
  56. data/spec/requests/ransackable_attributes_spec.rb +0 -79
  57. data/spec/requests/spree/api/addresses_controller_spec.rb +0 -57
  58. data/spec/requests/spree/api/checkouts_controller_spec.rb +0 -484
  59. data/spec/requests/spree/api/classifications_controller_spec.rb +0 -50
  60. data/spec/requests/spree/api/config_controller_spec.rb +0 -26
  61. data/spec/requests/spree/api/countries_controller_spec.rb +0 -48
  62. data/spec/requests/spree/api/coupon_codes_controller_spec.rb +0 -105
  63. data/spec/requests/spree/api/credit_cards_controller_spec.rb +0 -105
  64. data/spec/requests/spree/api/images_controller_spec.rb +0 -99
  65. data/spec/requests/spree/api/inventory_units_controller_spec.rb +0 -55
  66. data/spec/requests/spree/api/line_items_controller_spec.rb +0 -213
  67. data/spec/requests/spree/api/option_types_controller_spec.rb +0 -116
  68. data/spec/requests/spree/api/option_values_controller_spec.rb +0 -138
  69. data/spec/requests/spree/api/orders_controller_spec.rb +0 -954
  70. data/spec/requests/spree/api/payments_controller_spec.rb +0 -259
  71. data/spec/requests/spree/api/product_properties_controller_spec.rb +0 -114
  72. data/spec/requests/spree/api/products_controller_spec.rb +0 -422
  73. data/spec/requests/spree/api/promotion_application_spec.rb +0 -50
  74. data/spec/requests/spree/api/promotions_controller_spec.rb +0 -67
  75. data/spec/requests/spree/api/properties_controller_spec.rb +0 -102
  76. data/spec/requests/spree/api/return_authorizations_controller_spec.rb +0 -180
  77. data/spec/requests/spree/api/shipments_controller_spec.rb +0 -532
  78. data/spec/requests/spree/api/states_controller_spec.rb +0 -69
  79. data/spec/requests/spree/api/stock_items_controller_spec.rb +0 -311
  80. data/spec/requests/spree/api/stock_locations_controller_spec.rb +0 -170
  81. data/spec/requests/spree/api/stock_movements_controller_spec.rb +0 -81
  82. data/spec/requests/spree/api/store_credit_events_controller_spec.rb +0 -59
  83. data/spec/requests/spree/api/stores_controller_spec.rb +0 -134
  84. data/spec/requests/spree/api/taxonomies_controller_spec.rb +0 -114
  85. data/spec/requests/spree/api/taxons_controller_spec.rb +0 -217
  86. data/spec/requests/spree/api/unauthenticated_products_controller_spec.rb +0 -27
  87. data/spec/requests/spree/api/users_controller_spec.rb +0 -151
  88. data/spec/requests/spree/api/variants_controller_spec.rb +0 -340
  89. data/spec/requests/spree/api/zones_controller_spec.rb +0 -89
  90. data/spec/shared_examples/protect_product_actions.rb +0 -18
  91. data/spec/spec_helper.rb +0 -73
  92. data/spec/support/be_paginated_matcher.rb +0 -9
  93. data/spec/support/controller_hacks.rb +0 -43
  94. data/spec/support/database_cleaner.rb +0 -16
  95. data/spec/support/have_attributes_matcher.rb +0 -11
  96. data/spec/test_views/spree/api/widgets/_widget.json.jbuilder +0 -3
  97. data/spec/test_views/spree/api/widgets/index.json.jbuilder +0 -9
  98. data/spec/test_views/spree/api/widgets/new.json.jbuilder +0 -3
  99. data/spec/test_views/spree/api/widgets/show.json.jbuilder +0 -3
@@ -1,954 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- module Spree
6
- describe Api::OrdersController, type: :request do
7
- let!(:order) { create(:order) }
8
- let(:variant) { create(:variant) }
9
- let(:line_item) { create(:line_item) }
10
-
11
- let(:attributes) {
12
- [:number, :item_total, :display_total, :total,
13
- :state, :adjustment_total,
14
- :user_id, :created_at, :updated_at,
15
- :completed_at, :payment_total, :shipment_state,
16
- :payment_state, :email, :special_instructions,
17
- :total_quantity, :display_item_total, :currency]
18
- }
19
-
20
- let(:address_params) { { country_id: Country.first.id, state_id: State.first.id } }
21
-
22
- let(:current_api_user) do
23
- user = Spree.user_class.new(email: "spree@example.com")
24
- user.generate_spree_api_key!
25
- user
26
- end
27
-
28
- before do
29
- stub_authentication!
30
- end
31
-
32
- describe "POST create" do
33
- let(:target_user) { create :user }
34
- let(:date_override) { Time.parse('2015-01-01') }
35
- let(:attributes) { { user_id: target_user.id, created_at: date_override, email: target_user.email } }
36
-
37
- subject do
38
- post spree.api_orders_path, params: { order: attributes }
39
- response
40
- end
41
-
42
- context "when the current user cannot administrate the order" do
43
- custom_authorization! do |_|
44
- can :create, Spree::Order
45
- end
46
-
47
- it "does not include unpermitted params, or allow overriding the user" do
48
- subject
49
- expect(response).to be_successful
50
- order = Spree::Order.last
51
- expect(order.user).to eq current_api_user
52
- expect(order.email).to eq target_user.email
53
- end
54
-
55
- it { is_expected.to be_successful }
56
-
57
- context 'creating payment' do
58
- let(:attributes) { super().merge(payments_attributes: [{ payment_method_id: payment_method.id }]) }
59
-
60
- context "with allowed payment method" do
61
- let!(:payment_method) { create(:check_payment_method, name: "allowed" ) }
62
- it { is_expected.to be_successful }
63
- it "creates a payment" do
64
- expect {
65
- subject
66
- }.to change { Spree::Payment.count }.by(1)
67
- end
68
- end
69
-
70
- context "with disallowed payment method" do
71
- let!(:payment_method) { create(:check_payment_method, name: "forbidden", available_to_users: false) }
72
- it { is_expected.to be_not_found }
73
- it "creates no payments" do
74
- expect {
75
- subject
76
- }.not_to change { Spree::Payment.count }
77
- end
78
- end
79
- end
80
-
81
- context "with existing promotion" do
82
- let(:discount) { 2 }
83
- before do
84
- create(:promotion, :with_line_item_adjustment, apply_automatically: true, adjustment_rate: discount )
85
- end
86
-
87
- it "activates the promotion" do
88
- post spree.api_orders_path, params: { order: { line_items: { "0" => { variant_id: variant.to_param, quantity: 1 } } } }
89
- order = Order.last
90
- line_item = order.line_items.first
91
- expect(order.total).to eq(line_item.price - discount)
92
- end
93
- end
94
- end
95
-
96
- context "when the current user can administrate the order" do
97
- custom_authorization! do |_|
98
- can [:admin, :create], Spree::Order
99
- end
100
-
101
- it "it permits all params and allows overriding the user" do
102
- subject
103
- order = Spree::Order.last
104
- expect(order.user).to eq target_user
105
- expect(order.email).to eq target_user.email
106
- expect(order.created_at).to eq date_override
107
- end
108
-
109
- it { is_expected.to be_successful }
110
- end
111
-
112
- context 'when the line items have custom attributes' do
113
- it "can create an order with line items that have custom permitted attributes", :pending do
114
- PermittedAttributes.line_item_attributes << { options: [:some_option] }
115
- expect_any_instance_of(Spree::LineItem).to receive(:some_option=).once.with('4')
116
- post spree.api_orders_path, params: { order: { line_items: { "0" => { variant_id: variant.to_param, quantity: 5, options: { some_option: 4 } } } } }
117
- expect(response.status).to eq(201)
118
- order = Order.last
119
- expect(order.line_items.count).to eq(1)
120
- end
121
- end
122
- end
123
-
124
- describe "PUT update" do
125
- let(:user) { create :user }
126
- let(:order_params) { { number: "anothernumber", user_id: user.id, email: "foo@foobar.com" } }
127
- let(:can_admin) { false }
128
- subject do
129
- put spree.api_order_path(order), params: { order: order_params }
130
- response
131
- end
132
-
133
- context "when the user cannot administer the order" do
134
- custom_authorization! do |_|
135
- can [:update], Spree::Order
136
- end
137
-
138
- it "updates the user's email" do
139
- expect {
140
- subject
141
- }.to change { order.reload.email }.to("foo@foobar.com")
142
- end
143
-
144
- it { is_expected.to be_successful }
145
-
146
- it "does not associate users" do
147
- expect {
148
- subject
149
- }.not_to change { order.reload.user }
150
- end
151
-
152
- it "does not change forbidden attributes" do
153
- expect {
154
- subject
155
- }.to_not change{ order.reload.number }
156
- end
157
-
158
- context 'creating payment' do
159
- let!(:order) { create(:order_with_line_items) }
160
- let(:order_params) { super().merge(payments_attributes: [{ payment_method_id: payment_method.id }]) }
161
-
162
- context "with allowed payment method" do
163
- let!(:payment_method) { create(:check_payment_method, name: "allowed" ) }
164
- it { is_expected.to be_successful }
165
- it "creates a payment" do
166
- expect {
167
- subject
168
- }.to change { Spree::Payment.count }.by(1)
169
- end
170
-
171
- context 'trying to change the address' do
172
- let(:order_params) do
173
- super().merge(
174
- ship_address_attributes: {
175
- zipcode: '90100'
176
- }
177
- )
178
- end
179
-
180
- it 'changes the address' do
181
- expect {
182
- subject
183
- }.to change { order.reload.ship_address.zipcode }
184
- end
185
-
186
- it 'invalidates the shipments' do
187
- expect {
188
- subject
189
- }.to change { order.reload.shipments }.to([])
190
- end
191
- end
192
- end
193
-
194
- context "with disallowed payment method" do
195
- let!(:payment_method) { create(:check_payment_method, name: "forbidden", available_to_users: false) }
196
- it { is_expected.to be_not_found }
197
- it "creates no payments" do
198
- expect {
199
- subject
200
- }.not_to change { Spree::Payment.count }
201
- end
202
- end
203
- end
204
- end
205
-
206
- context "when the user can administer the order" do
207
- custom_authorization! do |_|
208
- can [:admin, :update], Spree::Order
209
- end
210
-
211
- it "will associate users" do
212
- expect {
213
- subject
214
- }.to change { order.reload.user }.to(user)
215
- end
216
-
217
- it "updates the otherwise forbidden attributes" do
218
- expect{ subject }.to change{ order.reload.number }.
219
- to("anothernumber")
220
- end
221
- end
222
- end
223
-
224
- it "cannot view all orders" do
225
- get spree.api_orders_path
226
- assert_unauthorized!
227
- end
228
-
229
- context "the current api user does not exist" do
230
- let(:current_api_user) { nil }
231
-
232
- it "returns a 401" do
233
- get spree.api_my_orders_path
234
- expect(response.status).to eq(401)
235
- end
236
- end
237
-
238
- context "the current api user is authenticated" do
239
- let(:current_api_user) { order.user }
240
- let(:store) { create(:store) }
241
- let(:order) { create(:order, line_items: [line_item], store: store) }
242
-
243
- it "can view all of their own orders for the current store" do
244
- get spree.api_my_orders_path, headers: { 'SERVER_NAME' => store.url }
245
-
246
- expect(response.status).to eq(200)
247
- expect(json_response["pages"]).to eq(1)
248
- expect(json_response["current_page"]).to eq(1)
249
- expect(json_response["orders"].length).to eq(1)
250
- expect(json_response["orders"].first["number"]).to eq(order.number)
251
- expect(json_response["orders"].first["line_items"].length).to eq(1)
252
- expect(json_response["orders"].first["line_items"].first["id"]).to eq(line_item.id)
253
- end
254
-
255
- it "cannot view orders for a different store" do
256
- get spree.api_my_orders_path, headers: { 'SERVER_NAME' => 'foo' }
257
-
258
- expect(response.status).to eq(200)
259
- expect(json_response["orders"].length).to eq(0)
260
- end
261
-
262
- it "can filter the returned results" do
263
- get spree.api_my_orders_path, params: { q: { completed_at_not_null: 1 } }, headers: { 'SERVER_NAME' => store.url }
264
-
265
- expect(response.status).to eq(200)
266
- expect(json_response["orders"].length).to eq(0)
267
- end
268
-
269
- it "returns orders in reverse chronological order by completed_at" do
270
- order.update_columns completed_at: Time.current, created_at: 3.days.ago
271
-
272
- order_two = Order.create user: order.user, completed_at: Time.current - 1.day, created_at: 2.days.ago, store: store
273
- expect(order_two.created_at).to be > order.created_at
274
- order_three = Order.create user: order.user, completed_at: nil, created_at: 1.day.ago, store: store
275
- expect(order_three.created_at).to be > order_two.created_at
276
- order_four = Order.create user: order.user, completed_at: nil, created_at: 0.days.ago, store: store
277
- expect(order_four.created_at).to be > order_three.created_at
278
-
279
- get spree.api_my_orders_path, headers: { 'SERVER_NAME' => store.url }
280
- expect(response.status).to eq(200)
281
- expect(json_response["pages"]).to eq(1)
282
- orders = json_response["orders"]
283
- expect(orders.length).to eq(4)
284
- expect(orders[0]["number"]).to eq(order.number)
285
- expect(orders[1]["number"]).to eq(order_two.number)
286
- expect([orders[2]["number"], orders[3]["number"]]).to match_array([order_three.number, order_four.number])
287
- end
288
- end
289
-
290
- describe 'current' do
291
- let(:current_api_user) { order.user }
292
- let!(:order) { create(:order, line_items: [line_item]) }
293
-
294
- it "uses the user's last_incomplete_spree_order logic with the current store" do
295
- expect(current_api_user).to receive(:last_incomplete_spree_order).with(store: Spree::Store.default)
296
- get spree.api_current_order_path(format: 'json')
297
- end
298
- end
299
-
300
- it "can view their own order" do
301
- allow_any_instance_of(Order).to receive_messages user: current_api_user
302
- get spree.api_order_path(order)
303
- expect(response.status).to eq(200)
304
- expect(json_response).to have_attributes(attributes)
305
- expect(json_response["adjustments"]).to be_empty
306
- end
307
-
308
- describe 'GET #show' do
309
- let(:order) { create :order_with_line_items }
310
- let(:adjustment) { FactoryBot.create(:adjustment, adjustable: order, order: order) }
311
-
312
- subject { get spree.api_order_path(order) }
313
-
314
- before do
315
- allow_any_instance_of(Order).to receive_messages user: current_api_user
316
- end
317
-
318
- context 'when inventory information is present' do
319
- it 'contains stock information on variant' do
320
- subject
321
- variant = json_response['line_items'][0]['variant']
322
- expect(variant).to_not be_nil
323
- expect(variant['in_stock']).to eq(false)
324
- expect(variant['total_on_hand']).to eq(0)
325
- expect(variant['is_backorderable']).to eq(true)
326
- expect(variant['is_destroyed']).to eq(false)
327
- end
328
- end
329
-
330
- context 'when an item does not track inventory' do
331
- before do
332
- order.line_items.first.variant.update!(track_inventory: false)
333
- end
334
-
335
- it 'contains stock information on variant' do
336
- subject
337
- variant = json_response['line_items'][0]['variant']
338
- expect(variant).to_not be_nil
339
- expect(variant['in_stock']).to eq(true)
340
- expect(variant['total_on_hand']).to eq(nil)
341
- expect(variant['is_backorderable']).to eq(true)
342
- expect(variant['is_destroyed']).to eq(false)
343
- end
344
- end
345
-
346
- context 'when shipment adjustments are present' do
347
- before do
348
- order.shipments.first.adjustments << adjustment
349
- end
350
-
351
- it 'contains adjustments on shipment' do
352
- subject
353
-
354
- # Test to insure shipment has adjustments
355
- shipment = json_response['shipments'][0]
356
- expect(shipment).to_not be_nil
357
- expect(shipment['adjustments'][0]).not_to be_empty
358
- expect(shipment['adjustments'][0]['label']).to eq(adjustment.label)
359
- end
360
- end
361
-
362
- context 'when credit cards are present' do
363
- let!(:payment) { create(:credit_card_payment, order: order, source: credit_card) }
364
- let(:credit_card) { create(:credit_card, address: create(:address)) }
365
-
366
- it 'contains the credit cards' do
367
- subject
368
-
369
- credit_cards = json_response['credit_cards']
370
- expect(credit_cards.size).to eq 1
371
- expect(credit_cards[0]['id']).to eq payment.source.id
372
- expect(credit_cards[0]['address']['id']).to eq credit_card.address_id
373
- end
374
-
375
- it 'renders the payment source view for gateway' do
376
- subject
377
- expect(response).to render_template partial: 'spree/api/payments/source_views/_gateway'
378
- end
379
- end
380
-
381
- context 'when store credit is present' do
382
- let!(:payment) { create(:store_credit_payment, order: order, source: store_credit) }
383
- let(:store_credit) { create(:store_credit) }
384
-
385
- it 'renders the payment source view for store credit' do
386
- subject
387
- expect(response).to render_template partial: 'spree/api/payments/source_views/_store_credit'
388
- end
389
- end
390
- end
391
-
392
- it "orders contain the basic checkout steps" do
393
- allow_any_instance_of(Order).to receive_messages user: current_api_user
394
- get spree.api_order_path(order)
395
- expect(response.status).to eq(200)
396
- expect(json_response["checkout_steps"]).to eq(%w[address delivery confirm complete])
397
- end
398
-
399
- it "can not view someone else's order" do
400
- allow_any_instance_of(Order).to receive_messages user: stub_model(Spree::LegacyUser)
401
- get spree.api_order_path(order)
402
- assert_unauthorized!
403
- end
404
-
405
- it "can view an order if the token is known" do
406
- get spree.api_order_path(order), params: { order_token: order.guest_token }
407
- expect(response.status).to eq(200)
408
- end
409
-
410
- it "can view an order if the token is passed in header" do
411
- get spree.api_order_path(order), headers: { "X-Spree-Order-Token" => order.guest_token }
412
- expect(response.status).to eq(200)
413
- end
414
-
415
- it "cannot cancel an order that doesn't belong to them" do
416
- order.update_attribute(:completed_at, Time.current)
417
- order.update_attribute(:shipment_state, "ready")
418
- put spree.cancel_api_order_path(order)
419
- assert_unauthorized!
420
- end
421
-
422
- it "can create an order" do
423
- post spree.api_orders_path, params: { order: { line_items: { "0" => { variant_id: variant.to_param, quantity: 5 } } } }
424
- expect(response.status).to eq(201)
425
-
426
- order = Order.last
427
- expect(order.line_items.count).to eq(1)
428
- expect(order.line_items.first.variant).to eq(variant)
429
- expect(order.line_items.first.quantity).to eq(5)
430
-
431
- expect(json_response['number']).to be_present
432
- expect(json_response["token"]).not_to be_blank
433
- expect(json_response["state"]).to eq("cart")
434
- expect(order.user).to eq(current_api_user)
435
- expect(order.email).to eq(current_api_user.email)
436
- expect(json_response["user_id"]).to eq(current_api_user.id)
437
- end
438
-
439
- it "assigns email when creating a new order" do
440
- post spree.api_orders_path, params: { order: { email: "guest@spreecommerce.com" } }
441
- expect(json_response['email']).not_to eq controller.current_api_user
442
- expect(json_response['email']).to eq "guest@spreecommerce.com"
443
- end
444
-
445
- # Regression test for https://github.com/spree/spree/issues/3404
446
- it "can specify additional parameters for a line item" do
447
- without_partial_double_verification do
448
- expect_any_instance_of(Spree::LineItem).to receive(:special=).with("foo")
449
- end
450
-
451
- allow_any_instance_of(Spree::Api::OrdersController).to receive_messages(permitted_line_item_attributes: [:id, :variant_id, :quantity, :special])
452
- post spree.api_orders_path, params: {
453
- order: {
454
- line_items: {
455
- "0" => {
456
- variant_id: variant.to_param, quantity: 5, special: "foo"
457
- }
458
- }
459
- }
460
- }
461
- expect(response.status).to eq(201)
462
- end
463
-
464
- it "cannot arbitrarily set the line items price" do
465
- post spree.api_orders_path, params: {
466
- order: {
467
- line_items: {
468
- "0" => {
469
- price: 33.0, variant_id: variant.to_param, quantity: 5
470
- }
471
- }
472
- }
473
- }
474
-
475
- expect(response.status).to eq 201
476
- expect(Order.last.line_items.first.price.to_f).to eq(variant.price)
477
- end
478
-
479
- context "admin user imports order" do
480
- let!(:current_api_user) { create :admin_user }
481
-
482
- it "is able to set any default unpermitted attribute" do
483
- post spree.api_orders_path, params: { order: { number: "WOW" } }
484
- expect(response.status).to eq 201
485
- expect(json_response['number']).to eq "WOW"
486
- end
487
- end
488
-
489
- it "can create an order without any parameters" do
490
- post spree.api_orders_path
491
- expect(response.status).to eq(201)
492
- expect(json_response["state"]).to eq("cart")
493
- end
494
-
495
- context "working with an order" do
496
- let(:variant) { create(:variant) }
497
- let!(:line_item) { order.contents.add(variant, 1) }
498
- let!(:payment_method) { create(:check_payment_method) }
499
-
500
- let(:address_params) { { country_id: country.id } }
501
- let(:billing_address) {
502
- { firstname: "Tiago", lastname: "Motta", address1: "Av Paulista",
503
- city: "Sao Paulo", zipcode: "01310-300", phone: "12345678",
504
- country_id: country.id }
505
- }
506
- let(:shipping_address) {
507
- { firstname: "Tiago", lastname: "Motta", address1: "Av Paulista",
508
- city: "Sao Paulo", zipcode: "01310-300", phone: "12345678",
509
- country_id: country.id }
510
- }
511
- let(:country) { create(:country, { name: "Brazil", iso_name: "BRAZIL", iso: "BR", iso3: "BRA", numcode: 76 }) }
512
-
513
- before { allow_any_instance_of(Order).to receive_messages user: current_api_user }
514
-
515
- it "updates quantities of existing line items" do
516
- put spree.api_order_path(order), params: { order: {
517
- line_items: {
518
- "0" => { id: line_item.id, quantity: 10 }
519
- }
520
- } }
521
-
522
- expect(response.status).to eq(200)
523
- expect(json_response['line_items'].count).to eq(1)
524
- expect(json_response['line_items'].first['quantity']).to eq(10)
525
- end
526
-
527
- it "adds an extra line item" do
528
- variant_two = create(:variant)
529
- put spree.api_order_path(order), params: { order: {
530
- line_items: {
531
- "0" => { id: line_item.id, quantity: 10 },
532
- "1" => { variant_id: variant_two.id, quantity: 1 }
533
- }
534
- } }
535
-
536
- expect(response.status).to eq(200)
537
- expect(json_response['line_items'].count).to eq(2)
538
- expect(json_response['line_items'][0]['quantity']).to eq(10)
539
- expect(json_response['line_items'][1]['variant_id']).to eq(variant_two.id)
540
- expect(json_response['line_items'][1]['quantity']).to eq(1)
541
- end
542
-
543
- it "cannot change the price of an existing line item" do
544
- put spree.api_order_path(order), params: { order: {
545
- line_items: {
546
- 0 => { id: line_item.id, price: 0 }
547
- }
548
- } }
549
-
550
- expect(response.status).to eq(200)
551
- expect(json_response['line_items'].count).to eq(1)
552
- expect(json_response['line_items'].first['price'].to_f).to_not eq(0)
553
- expect(json_response['line_items'].first['price'].to_f).to eq(line_item.variant.price)
554
- end
555
-
556
- it "can add billing address" do
557
- put spree.api_order_path(order), params: { order: { bill_address_attributes: billing_address } }
558
-
559
- expect(order.reload.bill_address).to_not be_nil
560
- end
561
-
562
- it "receives error message if trying to add billing address with errors" do
563
- billing_address[:firstname] = ""
564
-
565
- put spree.api_order_path(order), params: { order: { bill_address_attributes: billing_address } }
566
-
567
- expect(json_response['error']).not_to be_nil
568
- expect(json_response['errors']).not_to be_nil
569
- expect(json_response['errors']['bill_address.firstname'].first).to eq "can't be blank"
570
- end
571
-
572
- it "can add shipping address" do
573
- order.update!(ship_address_id: nil)
574
-
575
- expect {
576
- put spree.api_order_path(order), params: { order: { ship_address_attributes: shipping_address } }
577
- }.to change { order.reload.ship_address }.from(nil)
578
- end
579
-
580
- it "receives error message if trying to add shipping address with errors" do
581
- order.update!(ship_address_id: nil)
582
-
583
- shipping_address[:firstname] = ""
584
-
585
- put spree.api_order_path(order), params: { order: { ship_address_attributes: shipping_address } }
586
-
587
- expect(json_response['error']).not_to be_nil
588
- expect(json_response['errors']).not_to be_nil
589
- expect(json_response['errors']['ship_address.firstname'].first).to eq "can't be blank"
590
- end
591
-
592
- it "cannot set the user_id for the order" do
593
- user = Spree.user_class.create
594
- original_id = order.user_id
595
- put spree.api_order_path(order), params: { order: { user_id: user.id } }
596
- expect(response.status).to eq 200
597
- expect(json_response["user_id"]).to eq(original_id)
598
- end
599
-
600
- context "order has shipments" do
601
- before { order.create_proposed_shipments }
602
-
603
- it "clears out all existing shipments on line item update" do
604
- put spree.api_order_path(order), params: { order: {
605
- line_items: {
606
- 0 => { id: line_item.id, quantity: 10 }
607
- }
608
- } }
609
- expect(order.reload.shipments).to be_empty
610
- end
611
- end
612
-
613
- context "with a line item" do
614
- let(:order) { create(:order_with_line_items) }
615
- let(:line_item) { order.line_items.first }
616
-
617
- it "can empty an order" do
618
- create(:adjustment, order: order, adjustable: order)
619
- put spree.empty_api_order_path(order)
620
- expect(response.status).to eq(204)
621
- order.reload
622
- expect(order.line_items).to be_empty
623
- expect(order.adjustments).to be_empty
624
- end
625
-
626
- it "can list its line items with images" do
627
- order.line_items.first.variant.images.create!(attachment: image("thinking-cat.jpg"))
628
-
629
- get spree.api_order_path(order)
630
-
631
- expect(json_response['line_items'].first['variant']).to have_attributes([:images])
632
- end
633
-
634
- it "lists variants product id" do
635
- get spree.api_order_path(order)
636
-
637
- expect(json_response['line_items'].first['variant']).to have_attributes([:product_id])
638
- end
639
-
640
- it "includes the tax_total in the response" do
641
- get spree.api_order_path(order)
642
-
643
- expect(json_response['included_tax_total']).to eq('0.0')
644
- expect(json_response['additional_tax_total']).to eq('0.0')
645
- expect(json_response['display_included_tax_total']).to eq('$0.00')
646
- expect(json_response['display_additional_tax_total']).to eq('$0.00')
647
- end
648
-
649
- it "lists line item adjustments" do
650
- adjustment = create(:adjustment,
651
- label: "10% off!",
652
- order: order,
653
- adjustable: order.line_items.first)
654
- adjustment.update_column(:amount, 5)
655
- get spree.api_order_path(order)
656
-
657
- adjustment = json_response['line_items'].first['adjustments'].first
658
- expect(adjustment['label']).to eq("10% off!")
659
- expect(adjustment['amount']).to eq("5.0")
660
- end
661
-
662
- it "lists payments source without gateway info" do
663
- order.payments.push payment = create(:payment)
664
- get spree.api_order_path(order)
665
-
666
- source = json_response[:payments].first[:source]
667
- expect(source[:name]).to eq payment.source.name
668
- expect(source[:cc_type]).to eq payment.source.cc_type
669
- expect(source[:last_digits]).to eq payment.source.last_digits
670
- expect(source[:month]).to eq payment.source.month
671
- expect(source[:year]).to eq payment.source.year
672
- expect(source.key?(:gateway_customer_profile_id)).to be false
673
- expect(source.key?(:gateway_payment_profile_id)).to be false
674
- end
675
-
676
- context "when in delivery" do
677
- let!(:shipping_method) do
678
- FactoryBot.create(:shipping_method).tap do |shipping_method|
679
- shipping_method.calculator.preferred_amount = 10
680
- shipping_method.calculator.save
681
- end
682
- end
683
-
684
- before do
685
- order.next!
686
- order.next!
687
- order.save
688
- end
689
-
690
- it "includes the ship_total in the response" do
691
- get spree.api_order_path(order)
692
-
693
- expect(json_response['ship_total']).to eq '10.0'
694
- expect(json_response['display_ship_total']).to eq '$10.00'
695
- end
696
-
697
- it "returns available shipments for an order" do
698
- get spree.api_order_path(order)
699
- expect(response.status).to eq(200)
700
- expect(json_response["shipments"]).not_to be_empty
701
- shipment = json_response["shipments"][0]
702
- # Test for correct shipping method attributes
703
- # Regression test for https://github.com/spree/spree/issues/3206
704
- expect(shipment["shipping_methods"]).not_to be_nil
705
- json_shipping_method = shipment["shipping_methods"][0]
706
- expect(json_shipping_method["id"]).to eq(shipping_method.id)
707
- expect(json_shipping_method["name"]).to eq(shipping_method.name)
708
- expect(json_shipping_method["code"]).to eq(shipping_method.code)
709
- expect(json_shipping_method["zones"]).not_to be_empty
710
- expect(json_shipping_method["shipping_categories"]).not_to be_empty
711
-
712
- # Test for correct shipping rates attributes
713
- # Regression test for https://github.com/spree/spree/issues/3206
714
- expect(shipment["shipping_rates"]).not_to be_nil
715
- shipping_rate = shipment["shipping_rates"][0]
716
- expect(shipping_rate["name"]).to eq(json_shipping_method["name"])
717
- expect(shipping_rate["cost"]).to eq("10.0")
718
- expect(shipping_rate["selected"]).to be true
719
- expect(shipping_rate["display_cost"]).to eq("$10.00")
720
- expect(shipping_rate["shipping_method_code"]).to eq(json_shipping_method["code"])
721
-
722
- expect(shipment["stock_location_name"]).not_to be_blank
723
- manifest_item = shipment["manifest"][0]
724
- expect(manifest_item["quantity"]).to eq(1)
725
- expect(manifest_item["variant_id"]).to eq(order.line_items.first.variant_id)
726
- end
727
- end
728
- end
729
- end
730
-
731
- context "as an admin" do
732
- sign_in_as_admin!
733
-
734
- context "with no orders" do
735
- before { Spree::Order.delete_all }
736
- it "still returns a root :orders key" do
737
- get spree.api_orders_path
738
- expect(json_response["orders"]).to eq([])
739
- end
740
- end
741
-
742
- context "caching enabled" do
743
- before do
744
- ActionController::Base.perform_caching = true
745
- 3.times { Order.create }
746
- end
747
-
748
- it "returns unique orders" do
749
- get spree.api_orders_path
750
-
751
- orders = json_response[:orders]
752
- expect(orders.count).to be >= 3
753
- expect(orders.map { |order| order[:id] }).to match_array Order.pluck(:id)
754
- end
755
-
756
- after { ActionController::Base.perform_caching = false }
757
- end
758
-
759
- it "lists payments source with gateway info" do
760
- order.payments.push payment = create(:payment)
761
- get spree.api_order_path(order)
762
-
763
- source = json_response[:payments].first[:source]
764
- expect(source[:name]).to eq payment.source.name
765
- expect(source[:cc_type]).to eq payment.source.cc_type
766
- expect(source[:last_digits]).to eq payment.source.last_digits
767
- expect(source[:month]).to eq payment.source.month
768
- expect(source[:year]).to eq payment.source.year
769
- expect(source[:gateway_customer_profile_id]).to eq payment.source.gateway_customer_profile_id
770
- expect(source[:gateway_payment_profile_id]).to eq payment.source.gateway_payment_profile_id
771
- end
772
-
773
- context "with two orders" do
774
- before { create(:order) }
775
-
776
- it "can view all orders" do
777
- get spree.api_orders_path
778
- expect(json_response["orders"].first).to have_attributes(attributes)
779
- expect(json_response["count"]).to eq(2)
780
- expect(json_response["current_page"]).to eq(1)
781
- expect(json_response["pages"]).to eq(1)
782
- end
783
-
784
- # Test for https://github.com/spree/spree/issues/1763
785
- it "can control the page size through a parameter" do
786
- get spree.api_orders_path, params: { per_page: 1 }
787
- expect(json_response["orders"].count).to eq(1)
788
- expect(json_response["orders"].first).to have_attributes(attributes)
789
- expect(json_response["count"]).to eq(1)
790
- expect(json_response["current_page"]).to eq(1)
791
- expect(json_response["pages"]).to eq(2)
792
- end
793
- end
794
-
795
- context "search" do
796
- before do
797
- create(:order)
798
- Spree::Order.last.update_attribute(:email, 'spree@spreecommerce.com')
799
- end
800
-
801
- let(:expected_result) { Spree::Order.last }
802
-
803
- it "can query the results through a parameter" do
804
- get spree.api_orders_path, params: { q: { email_cont: 'spree' } }
805
- expect(json_response["orders"].count).to eq(1)
806
- expect(json_response["orders"].first).to have_attributes(attributes)
807
- expect(json_response["orders"].first["email"]).to eq(expected_result.email)
808
- expect(json_response["count"]).to eq(1)
809
- expect(json_response["current_page"]).to eq(1)
810
- expect(json_response["pages"]).to eq(1)
811
- end
812
- end
813
-
814
- context "creation" do
815
- it "can create an order without any parameters" do
816
- post spree.api_orders_path
817
- expect(response.status).to eq(201)
818
- expect(json_response["state"]).to eq("cart")
819
- end
820
-
821
- it "can arbitrarily set the line items price" do
822
- post spree.api_orders_path, params: {
823
- order: {
824
- line_items: {
825
- "0" => {
826
- price: 33.0, variant_id: variant.to_param, quantity: 5
827
- }
828
- }
829
- }
830
- }
831
- expect(response.status).to eq 201
832
- expect(Order.last.line_items.first.price.to_f).to eq(33.0)
833
- end
834
-
835
- it "can set the user_id for the order" do
836
- user = Spree.user_class.create
837
- post spree.api_orders_path, params: { order: { user_id: user.id } }
838
- expect(response.status).to eq 201
839
- expect(json_response["user_id"]).to eq(user.id)
840
- end
841
-
842
- context "with payment" do
843
- let(:params) do
844
- {
845
- payments: [{
846
- amount: '10.0',
847
- payment_method: create(:payment_method).name,
848
- source: {
849
- month: "01",
850
- year: Date.today.year.to_s.last(2),
851
- cc_type: "123",
852
- last_digits: "1111",
853
- name: "Credit Card"
854
- }
855
- }]
856
- }
857
- end
858
-
859
- context "with source" do
860
- it "creates a payment" do
861
- post spree.api_orders_path, params: { order: params }
862
- payment = json_response['payments'].first
863
-
864
- expect(response.status).to eq 201
865
- expect(payment['amount']).to eql "10.0"
866
- expect(payment['source']['last_digits']).to eql "1111"
867
- end
868
-
869
- context "when payment_method is missing" do
870
- it "returns an error" do
871
- params[:payments][0].delete(:payment_method)
872
- post spree.api_orders_path, params: { order: params }
873
- expect(response.status).to eq 404
874
- end
875
- end
876
- end
877
- end
878
- end
879
-
880
- context "updating" do
881
- it "can set the user_id for the order" do
882
- user = Spree.user_class.create
883
- put spree.api_order_path(order), params: { order: { user_id: user.id } }
884
- expect(response.status).to eq 200
885
- expect(json_response["user_id"]).to eq(user.id)
886
- end
887
- end
888
-
889
- context "can cancel an order" do
890
- before do
891
- stub_spree_preferences(mails_from: "spree@example.com")
892
-
893
- order.completed_at = Time.current
894
- order.state = 'complete'
895
- order.shipment_state = 'ready'
896
- order.save!
897
- end
898
-
899
- specify do
900
- put spree.cancel_api_order_path(order)
901
- expect(json_response["state"]).to eq("canceled")
902
- expect(json_response["canceler_id"]).to eq(current_api_user.id)
903
- end
904
- end
905
- end
906
-
907
- describe '#apply_coupon_code' do
908
- let(:promo) { create(:promotion_with_item_adjustment, code: 'abc') }
909
- let(:promo_code) { promo.codes.first }
910
-
911
- before do
912
- allow_any_instance_of(Order).to receive_messages user: current_api_user
913
- end
914
-
915
- context 'when successful' do
916
- let(:order) { create(:order_with_line_items) }
917
-
918
- it 'applies the coupon' do
919
- expect(Spree::Deprecation).to receive(:warn)
920
-
921
- put spree.apply_coupon_code_api_order_path(order), params: { coupon_code: promo_code.value }
922
-
923
- expect(response.status).to eq 200
924
- expect(order.reload.promotions).to eq [promo]
925
- expect(json_response).to eq({
926
- "success" => I18n.t('spree.coupon_code_applied'),
927
- "error" => nil,
928
- "successful" => true,
929
- "status_code" => "coupon_code_applied"
930
- })
931
- end
932
- end
933
-
934
- context 'when unsuccessful' do
935
- let(:order) { create(:order) } # no line items to apply the code to
936
-
937
- it 'returns an error' do
938
- expect(Spree::Deprecation).to receive(:warn)
939
-
940
- put spree.apply_coupon_code_api_order_path(order), params: { coupon_code: promo_code.value }
941
-
942
- expect(response.status).to eq 422
943
- expect(order.reload.promotions).to eq []
944
- expect(json_response).to eq({
945
- "success" => nil,
946
- "error" => I18n.t('spree.coupon_code_unknown_error'),
947
- "successful" => false,
948
- "status_code" => "coupon_code_unknown_error"
949
- })
950
- end
951
- end
952
- end
953
- end
954
- end