solidus_api 2.10.5 → 2.11.0

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