solidus_api 2.10.1 → 2.11.2

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 +18 -15
  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 +8 -2
  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 +11 -2
  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 +17 -117
  46. data/openapi/api.oas2.yml +0 -6105
  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 -456
  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 -931
  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,931 +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_params) { super().merge(payments_attributes: [{ payment_method_id: payment_method.id }]) }
160
-
161
- context "with allowed payment method" do
162
- let!(:payment_method) { create(:check_payment_method, name: "allowed" ) }
163
- it { is_expected.to be_successful }
164
- it "creates a payment" do
165
- expect {
166
- subject
167
- }.to change { Spree::Payment.count }.by(1)
168
- end
169
- end
170
-
171
- context "with disallowed payment method" do
172
- let!(:payment_method) { create(:check_payment_method, name: "forbidden", available_to_users: false) }
173
- it { is_expected.to be_not_found }
174
- it "creates no payments" do
175
- expect {
176
- subject
177
- }.not_to change { Spree::Payment.count }
178
- end
179
- end
180
- end
181
- end
182
-
183
- context "when the user can administer the order" do
184
- custom_authorization! do |_|
185
- can [:admin, :update], Spree::Order
186
- end
187
-
188
- it "will associate users" do
189
- expect {
190
- subject
191
- }.to change { order.reload.user }.to(user)
192
- end
193
-
194
- it "updates the otherwise forbidden attributes" do
195
- expect{ subject }.to change{ order.reload.number }.
196
- to("anothernumber")
197
- end
198
- end
199
- end
200
-
201
- it "cannot view all orders" do
202
- get spree.api_orders_path
203
- assert_unauthorized!
204
- end
205
-
206
- context "the current api user does not exist" do
207
- let(:current_api_user) { nil }
208
-
209
- it "returns a 401" do
210
- get spree.api_my_orders_path
211
- expect(response.status).to eq(401)
212
- end
213
- end
214
-
215
- context "the current api user is authenticated" do
216
- let(:current_api_user) { order.user }
217
- let(:store) { create(:store) }
218
- let(:order) { create(:order, line_items: [line_item], store: store) }
219
-
220
- it "can view all of their own orders for the current store" do
221
- get spree.api_my_orders_path, headers: { 'SERVER_NAME' => store.url }
222
-
223
- expect(response.status).to eq(200)
224
- expect(json_response["pages"]).to eq(1)
225
- expect(json_response["current_page"]).to eq(1)
226
- expect(json_response["orders"].length).to eq(1)
227
- expect(json_response["orders"].first["number"]).to eq(order.number)
228
- expect(json_response["orders"].first["line_items"].length).to eq(1)
229
- expect(json_response["orders"].first["line_items"].first["id"]).to eq(line_item.id)
230
- end
231
-
232
- it "cannot view orders for a different store" do
233
- get spree.api_my_orders_path, headers: { 'SERVER_NAME' => 'foo' }
234
-
235
- expect(response.status).to eq(200)
236
- expect(json_response["orders"].length).to eq(0)
237
- end
238
-
239
- it "can filter the returned results" do
240
- get spree.api_my_orders_path, params: { q: { completed_at_not_null: 1 } }, headers: { 'SERVER_NAME' => store.url }
241
-
242
- expect(response.status).to eq(200)
243
- expect(json_response["orders"].length).to eq(0)
244
- end
245
-
246
- it "returns orders in reverse chronological order by completed_at" do
247
- order.update_columns completed_at: Time.current, created_at: 3.days.ago
248
-
249
- order_two = Order.create user: order.user, completed_at: Time.current - 1.day, created_at: 2.days.ago, store: store
250
- expect(order_two.created_at).to be > order.created_at
251
- order_three = Order.create user: order.user, completed_at: nil, created_at: 1.day.ago, store: store
252
- expect(order_three.created_at).to be > order_two.created_at
253
- order_four = Order.create user: order.user, completed_at: nil, created_at: 0.days.ago, store: store
254
- expect(order_four.created_at).to be > order_three.created_at
255
-
256
- get spree.api_my_orders_path, headers: { 'SERVER_NAME' => store.url }
257
- expect(response.status).to eq(200)
258
- expect(json_response["pages"]).to eq(1)
259
- orders = json_response["orders"]
260
- expect(orders.length).to eq(4)
261
- expect(orders[0]["number"]).to eq(order.number)
262
- expect(orders[1]["number"]).to eq(order_two.number)
263
- expect([orders[2]["number"], orders[3]["number"]]).to match_array([order_three.number, order_four.number])
264
- end
265
- end
266
-
267
- describe 'current' do
268
- let(:current_api_user) { order.user }
269
- let!(:order) { create(:order, line_items: [line_item]) }
270
-
271
- it "uses the user's last_incomplete_spree_order logic with the current store" do
272
- expect(current_api_user).to receive(:last_incomplete_spree_order).with(store: Spree::Store.default)
273
- get spree.api_current_order_path(format: 'json')
274
- end
275
- end
276
-
277
- it "can view their own order" do
278
- allow_any_instance_of(Order).to receive_messages user: current_api_user
279
- get spree.api_order_path(order)
280
- expect(response.status).to eq(200)
281
- expect(json_response).to have_attributes(attributes)
282
- expect(json_response["adjustments"]).to be_empty
283
- end
284
-
285
- describe 'GET #show' do
286
- let(:order) { create :order_with_line_items }
287
- let(:adjustment) { FactoryBot.create(:adjustment, adjustable: order, order: order) }
288
-
289
- subject { get spree.api_order_path(order) }
290
-
291
- before do
292
- allow_any_instance_of(Order).to receive_messages user: current_api_user
293
- end
294
-
295
- context 'when inventory information is present' do
296
- it 'contains stock information on variant' do
297
- subject
298
- variant = json_response['line_items'][0]['variant']
299
- expect(variant).to_not be_nil
300
- expect(variant['in_stock']).to eq(false)
301
- expect(variant['total_on_hand']).to eq(0)
302
- expect(variant['is_backorderable']).to eq(true)
303
- expect(variant['is_destroyed']).to eq(false)
304
- end
305
- end
306
-
307
- context 'when an item does not track inventory' do
308
- before do
309
- order.line_items.first.variant.update!(track_inventory: false)
310
- end
311
-
312
- it 'contains stock information on variant' do
313
- subject
314
- variant = json_response['line_items'][0]['variant']
315
- expect(variant).to_not be_nil
316
- expect(variant['in_stock']).to eq(true)
317
- expect(variant['total_on_hand']).to eq(nil)
318
- expect(variant['is_backorderable']).to eq(true)
319
- expect(variant['is_destroyed']).to eq(false)
320
- end
321
- end
322
-
323
- context 'when shipment adjustments are present' do
324
- before do
325
- order.shipments.first.adjustments << adjustment
326
- end
327
-
328
- it 'contains adjustments on shipment' do
329
- subject
330
-
331
- # Test to insure shipment has adjustments
332
- shipment = json_response['shipments'][0]
333
- expect(shipment).to_not be_nil
334
- expect(shipment['adjustments'][0]).not_to be_empty
335
- expect(shipment['adjustments'][0]['label']).to eq(adjustment.label)
336
- end
337
- end
338
-
339
- context 'when credit cards are present' do
340
- let!(:payment) { create(:credit_card_payment, order: order, source: credit_card) }
341
- let(:credit_card) { create(:credit_card, address: create(:address)) }
342
-
343
- it 'contains the credit cards' do
344
- subject
345
-
346
- credit_cards = json_response['credit_cards']
347
- expect(credit_cards.size).to eq 1
348
- expect(credit_cards[0]['id']).to eq payment.source.id
349
- expect(credit_cards[0]['address']['id']).to eq credit_card.address_id
350
- end
351
-
352
- it 'renders the payment source view for gateway' do
353
- subject
354
- expect(response).to render_template partial: 'spree/api/payments/source_views/_gateway'
355
- end
356
- end
357
-
358
- context 'when store credit is present' do
359
- let!(:payment) { create(:store_credit_payment, order: order, source: store_credit) }
360
- let(:store_credit) { create(:store_credit) }
361
-
362
- it 'renders the payment source view for store credit' do
363
- subject
364
- expect(response).to render_template partial: 'spree/api/payments/source_views/_store_credit'
365
- end
366
- end
367
- end
368
-
369
- it "orders contain the basic checkout steps" do
370
- allow_any_instance_of(Order).to receive_messages user: current_api_user
371
- get spree.api_order_path(order)
372
- expect(response.status).to eq(200)
373
- expect(json_response["checkout_steps"]).to eq(%w[address delivery confirm complete])
374
- end
375
-
376
- it "can not view someone else's order" do
377
- allow_any_instance_of(Order).to receive_messages user: stub_model(Spree::LegacyUser)
378
- get spree.api_order_path(order)
379
- assert_unauthorized!
380
- end
381
-
382
- it "can view an order if the token is known" do
383
- get spree.api_order_path(order), params: { order_token: order.guest_token }
384
- expect(response.status).to eq(200)
385
- end
386
-
387
- it "can view an order if the token is passed in header" do
388
- get spree.api_order_path(order), headers: { "X-Spree-Order-Token" => order.guest_token }
389
- expect(response.status).to eq(200)
390
- end
391
-
392
- it "cannot cancel an order that doesn't belong to them" do
393
- order.update_attribute(:completed_at, Time.current)
394
- order.update_attribute(:shipment_state, "ready")
395
- put spree.cancel_api_order_path(order)
396
- assert_unauthorized!
397
- end
398
-
399
- it "can create an order" do
400
- post spree.api_orders_path, params: { order: { line_items: { "0" => { variant_id: variant.to_param, quantity: 5 } } } }
401
- expect(response.status).to eq(201)
402
-
403
- order = Order.last
404
- expect(order.line_items.count).to eq(1)
405
- expect(order.line_items.first.variant).to eq(variant)
406
- expect(order.line_items.first.quantity).to eq(5)
407
-
408
- expect(json_response['number']).to be_present
409
- expect(json_response["token"]).not_to be_blank
410
- expect(json_response["state"]).to eq("cart")
411
- expect(order.user).to eq(current_api_user)
412
- expect(order.email).to eq(current_api_user.email)
413
- expect(json_response["user_id"]).to eq(current_api_user.id)
414
- end
415
-
416
- it "assigns email when creating a new order" do
417
- post spree.api_orders_path, params: { order: { email: "guest@spreecommerce.com" } }
418
- expect(json_response['email']).not_to eq controller.current_api_user
419
- expect(json_response['email']).to eq "guest@spreecommerce.com"
420
- end
421
-
422
- # Regression test for https://github.com/spree/spree/issues/3404
423
- it "can specify additional parameters for a line item" do
424
- without_partial_double_verification do
425
- expect_any_instance_of(Spree::LineItem).to receive(:special=).with("foo")
426
- end
427
-
428
- allow_any_instance_of(Spree::Api::OrdersController).to receive_messages(permitted_line_item_attributes: [:id, :variant_id, :quantity, :special])
429
- post spree.api_orders_path, params: {
430
- order: {
431
- line_items: {
432
- "0" => {
433
- variant_id: variant.to_param, quantity: 5, special: "foo"
434
- }
435
- }
436
- }
437
- }
438
- expect(response.status).to eq(201)
439
- end
440
-
441
- it "cannot arbitrarily set the line items price" do
442
- post spree.api_orders_path, params: {
443
- order: {
444
- line_items: {
445
- "0" => {
446
- price: 33.0, variant_id: variant.to_param, quantity: 5
447
- }
448
- }
449
- }
450
- }
451
-
452
- expect(response.status).to eq 201
453
- expect(Order.last.line_items.first.price.to_f).to eq(variant.price)
454
- end
455
-
456
- context "admin user imports order" do
457
- let!(:current_api_user) { create :admin_user }
458
-
459
- it "is able to set any default unpermitted attribute" do
460
- post spree.api_orders_path, params: { order: { number: "WOW" } }
461
- expect(response.status).to eq 201
462
- expect(json_response['number']).to eq "WOW"
463
- end
464
- end
465
-
466
- it "can create an order without any parameters" do
467
- post spree.api_orders_path
468
- expect(response.status).to eq(201)
469
- expect(json_response["state"]).to eq("cart")
470
- end
471
-
472
- context "working with an order" do
473
- let(:variant) { create(:variant) }
474
- let!(:line_item) { order.contents.add(variant, 1) }
475
- let!(:payment_method) { create(:check_payment_method) }
476
-
477
- let(:address_params) { { country_id: country.id } }
478
- let(:billing_address) {
479
- { firstname: "Tiago", lastname: "Motta", address1: "Av Paulista",
480
- city: "Sao Paulo", zipcode: "01310-300", phone: "12345678",
481
- country_id: country.id }
482
- }
483
- let(:shipping_address) {
484
- { firstname: "Tiago", lastname: "Motta", address1: "Av Paulista",
485
- city: "Sao Paulo", zipcode: "01310-300", phone: "12345678",
486
- country_id: country.id }
487
- }
488
- let(:country) { create(:country, { name: "Brazil", iso_name: "BRAZIL", iso: "BR", iso3: "BRA", numcode: 76 }) }
489
-
490
- before { allow_any_instance_of(Order).to receive_messages user: current_api_user }
491
-
492
- it "updates quantities of existing line items" do
493
- put spree.api_order_path(order), params: { order: {
494
- line_items: {
495
- "0" => { id: line_item.id, quantity: 10 }
496
- }
497
- } }
498
-
499
- expect(response.status).to eq(200)
500
- expect(json_response['line_items'].count).to eq(1)
501
- expect(json_response['line_items'].first['quantity']).to eq(10)
502
- end
503
-
504
- it "adds an extra line item" do
505
- variant_two = create(:variant)
506
- put spree.api_order_path(order), params: { order: {
507
- line_items: {
508
- "0" => { id: line_item.id, quantity: 10 },
509
- "1" => { variant_id: variant_two.id, quantity: 1 }
510
- }
511
- } }
512
-
513
- expect(response.status).to eq(200)
514
- expect(json_response['line_items'].count).to eq(2)
515
- expect(json_response['line_items'][0]['quantity']).to eq(10)
516
- expect(json_response['line_items'][1]['variant_id']).to eq(variant_two.id)
517
- expect(json_response['line_items'][1]['quantity']).to eq(1)
518
- end
519
-
520
- it "cannot change the price of an existing line item" do
521
- put spree.api_order_path(order), params: { order: {
522
- line_items: {
523
- 0 => { id: line_item.id, price: 0 }
524
- }
525
- } }
526
-
527
- expect(response.status).to eq(200)
528
- expect(json_response['line_items'].count).to eq(1)
529
- expect(json_response['line_items'].first['price'].to_f).to_not eq(0)
530
- expect(json_response['line_items'].first['price'].to_f).to eq(line_item.variant.price)
531
- end
532
-
533
- it "can add billing address" do
534
- put spree.api_order_path(order), params: { order: { bill_address_attributes: billing_address } }
535
-
536
- expect(order.reload.bill_address).to_not be_nil
537
- end
538
-
539
- it "receives error message if trying to add billing address with errors" do
540
- billing_address[:firstname] = ""
541
-
542
- put spree.api_order_path(order), params: { order: { bill_address_attributes: billing_address } }
543
-
544
- expect(json_response['error']).not_to be_nil
545
- expect(json_response['errors']).not_to be_nil
546
- expect(json_response['errors']['bill_address.firstname'].first).to eq "can't be blank"
547
- end
548
-
549
- it "can add shipping address" do
550
- order.update!(ship_address_id: nil)
551
-
552
- expect {
553
- put spree.api_order_path(order), params: { order: { ship_address_attributes: shipping_address } }
554
- }.to change { order.reload.ship_address }.from(nil)
555
- end
556
-
557
- it "receives error message if trying to add shipping address with errors" do
558
- order.update!(ship_address_id: nil)
559
-
560
- shipping_address[:firstname] = ""
561
-
562
- put spree.api_order_path(order), params: { order: { ship_address_attributes: shipping_address } }
563
-
564
- expect(json_response['error']).not_to be_nil
565
- expect(json_response['errors']).not_to be_nil
566
- expect(json_response['errors']['ship_address.firstname'].first).to eq "can't be blank"
567
- end
568
-
569
- it "cannot set the user_id for the order" do
570
- user = Spree.user_class.create
571
- original_id = order.user_id
572
- put spree.api_order_path(order), params: { order: { user_id: user.id } }
573
- expect(response.status).to eq 200
574
- expect(json_response["user_id"]).to eq(original_id)
575
- end
576
-
577
- context "order has shipments" do
578
- before { order.create_proposed_shipments }
579
-
580
- it "clears out all existing shipments on line item update" do
581
- put spree.api_order_path(order), params: { order: {
582
- line_items: {
583
- 0 => { id: line_item.id, quantity: 10 }
584
- }
585
- } }
586
- expect(order.reload.shipments).to be_empty
587
- end
588
- end
589
-
590
- context "with a line item" do
591
- let(:order) { create(:order_with_line_items) }
592
- let(:line_item) { order.line_items.first }
593
-
594
- it "can empty an order" do
595
- create(:adjustment, order: order, adjustable: order)
596
- put spree.empty_api_order_path(order)
597
- expect(response.status).to eq(204)
598
- order.reload
599
- expect(order.line_items).to be_empty
600
- expect(order.adjustments).to be_empty
601
- end
602
-
603
- it "can list its line items with images" do
604
- order.line_items.first.variant.images.create!(attachment: image("thinking-cat.jpg"))
605
-
606
- get spree.api_order_path(order)
607
-
608
- expect(json_response['line_items'].first['variant']).to have_attributes([:images])
609
- end
610
-
611
- it "lists variants product id" do
612
- get spree.api_order_path(order)
613
-
614
- expect(json_response['line_items'].first['variant']).to have_attributes([:product_id])
615
- end
616
-
617
- it "includes the tax_total in the response" do
618
- get spree.api_order_path(order)
619
-
620
- expect(json_response['included_tax_total']).to eq('0.0')
621
- expect(json_response['additional_tax_total']).to eq('0.0')
622
- expect(json_response['display_included_tax_total']).to eq('$0.00')
623
- expect(json_response['display_additional_tax_total']).to eq('$0.00')
624
- end
625
-
626
- it "lists line item adjustments" do
627
- adjustment = create(:adjustment,
628
- label: "10% off!",
629
- order: order,
630
- adjustable: order.line_items.first)
631
- adjustment.update_column(:amount, 5)
632
- get spree.api_order_path(order)
633
-
634
- adjustment = json_response['line_items'].first['adjustments'].first
635
- expect(adjustment['label']).to eq("10% off!")
636
- expect(adjustment['amount']).to eq("5.0")
637
- end
638
-
639
- it "lists payments source without gateway info" do
640
- order.payments.push payment = create(:payment)
641
- get spree.api_order_path(order)
642
-
643
- source = json_response[:payments].first[:source]
644
- expect(source[:name]).to eq payment.source.name
645
- expect(source[:cc_type]).to eq payment.source.cc_type
646
- expect(source[:last_digits]).to eq payment.source.last_digits
647
- expect(source[:month]).to eq payment.source.month
648
- expect(source[:year]).to eq payment.source.year
649
- expect(source.key?(:gateway_customer_profile_id)).to be false
650
- expect(source.key?(:gateway_payment_profile_id)).to be false
651
- end
652
-
653
- context "when in delivery" do
654
- let!(:shipping_method) do
655
- FactoryBot.create(:shipping_method).tap do |shipping_method|
656
- shipping_method.calculator.preferred_amount = 10
657
- shipping_method.calculator.save
658
- end
659
- end
660
-
661
- before do
662
- order.next!
663
- order.next!
664
- order.save
665
- end
666
-
667
- it "includes the ship_total in the response" do
668
- get spree.api_order_path(order)
669
-
670
- expect(json_response['ship_total']).to eq '10.0'
671
- expect(json_response['display_ship_total']).to eq '$10.00'
672
- end
673
-
674
- it "returns available shipments for an order" do
675
- get spree.api_order_path(order)
676
- expect(response.status).to eq(200)
677
- expect(json_response["shipments"]).not_to be_empty
678
- shipment = json_response["shipments"][0]
679
- # Test for correct shipping method attributes
680
- # Regression test for https://github.com/spree/spree/issues/3206
681
- expect(shipment["shipping_methods"]).not_to be_nil
682
- json_shipping_method = shipment["shipping_methods"][0]
683
- expect(json_shipping_method["id"]).to eq(shipping_method.id)
684
- expect(json_shipping_method["name"]).to eq(shipping_method.name)
685
- expect(json_shipping_method["code"]).to eq(shipping_method.code)
686
- expect(json_shipping_method["zones"]).not_to be_empty
687
- expect(json_shipping_method["shipping_categories"]).not_to be_empty
688
-
689
- # Test for correct shipping rates attributes
690
- # Regression test for https://github.com/spree/spree/issues/3206
691
- expect(shipment["shipping_rates"]).not_to be_nil
692
- shipping_rate = shipment["shipping_rates"][0]
693
- expect(shipping_rate["name"]).to eq(json_shipping_method["name"])
694
- expect(shipping_rate["cost"]).to eq("10.0")
695
- expect(shipping_rate["selected"]).to be true
696
- expect(shipping_rate["display_cost"]).to eq("$10.00")
697
- expect(shipping_rate["shipping_method_code"]).to eq(json_shipping_method["code"])
698
-
699
- expect(shipment["stock_location_name"]).not_to be_blank
700
- manifest_item = shipment["manifest"][0]
701
- expect(manifest_item["quantity"]).to eq(1)
702
- expect(manifest_item["variant_id"]).to eq(order.line_items.first.variant_id)
703
- end
704
- end
705
- end
706
- end
707
-
708
- context "as an admin" do
709
- sign_in_as_admin!
710
-
711
- context "with no orders" do
712
- before { Spree::Order.delete_all }
713
- it "still returns a root :orders key" do
714
- get spree.api_orders_path
715
- expect(json_response["orders"]).to eq([])
716
- end
717
- end
718
-
719
- context "caching enabled" do
720
- before do
721
- ActionController::Base.perform_caching = true
722
- 3.times { Order.create }
723
- end
724
-
725
- it "returns unique orders" do
726
- get spree.api_orders_path
727
-
728
- orders = json_response[:orders]
729
- expect(orders.count).to be >= 3
730
- expect(orders.map { |order| order[:id] }).to match_array Order.pluck(:id)
731
- end
732
-
733
- after { ActionController::Base.perform_caching = false }
734
- end
735
-
736
- it "lists payments source with gateway info" do
737
- order.payments.push payment = create(:payment)
738
- get spree.api_order_path(order)
739
-
740
- source = json_response[:payments].first[:source]
741
- expect(source[:name]).to eq payment.source.name
742
- expect(source[:cc_type]).to eq payment.source.cc_type
743
- expect(source[:last_digits]).to eq payment.source.last_digits
744
- expect(source[:month]).to eq payment.source.month
745
- expect(source[:year]).to eq payment.source.year
746
- expect(source[:gateway_customer_profile_id]).to eq payment.source.gateway_customer_profile_id
747
- expect(source[:gateway_payment_profile_id]).to eq payment.source.gateway_payment_profile_id
748
- end
749
-
750
- context "with two orders" do
751
- before { create(:order) }
752
-
753
- it "can view all orders" do
754
- get spree.api_orders_path
755
- expect(json_response["orders"].first).to have_attributes(attributes)
756
- expect(json_response["count"]).to eq(2)
757
- expect(json_response["current_page"]).to eq(1)
758
- expect(json_response["pages"]).to eq(1)
759
- end
760
-
761
- # Test for https://github.com/spree/spree/issues/1763
762
- it "can control the page size through a parameter" do
763
- get spree.api_orders_path, params: { per_page: 1 }
764
- expect(json_response["orders"].count).to eq(1)
765
- expect(json_response["orders"].first).to have_attributes(attributes)
766
- expect(json_response["count"]).to eq(1)
767
- expect(json_response["current_page"]).to eq(1)
768
- expect(json_response["pages"]).to eq(2)
769
- end
770
- end
771
-
772
- context "search" do
773
- before do
774
- create(:order)
775
- Spree::Order.last.update_attribute(:email, 'spree@spreecommerce.com')
776
- end
777
-
778
- let(:expected_result) { Spree::Order.last }
779
-
780
- it "can query the results through a parameter" do
781
- get spree.api_orders_path, params: { q: { email_cont: 'spree' } }
782
- expect(json_response["orders"].count).to eq(1)
783
- expect(json_response["orders"].first).to have_attributes(attributes)
784
- expect(json_response["orders"].first["email"]).to eq(expected_result.email)
785
- expect(json_response["count"]).to eq(1)
786
- expect(json_response["current_page"]).to eq(1)
787
- expect(json_response["pages"]).to eq(1)
788
- end
789
- end
790
-
791
- context "creation" do
792
- it "can create an order without any parameters" do
793
- post spree.api_orders_path
794
- expect(response.status).to eq(201)
795
- expect(json_response["state"]).to eq("cart")
796
- end
797
-
798
- it "can arbitrarily set the line items price" do
799
- post spree.api_orders_path, params: {
800
- order: {
801
- line_items: {
802
- "0" => {
803
- price: 33.0, variant_id: variant.to_param, quantity: 5
804
- }
805
- }
806
- }
807
- }
808
- expect(response.status).to eq 201
809
- expect(Order.last.line_items.first.price.to_f).to eq(33.0)
810
- end
811
-
812
- it "can set the user_id for the order" do
813
- user = Spree.user_class.create
814
- post spree.api_orders_path, params: { order: { user_id: user.id } }
815
- expect(response.status).to eq 201
816
- expect(json_response["user_id"]).to eq(user.id)
817
- end
818
-
819
- context "with payment" do
820
- let(:params) do
821
- {
822
- payments: [{
823
- amount: '10.0',
824
- payment_method: create(:payment_method).name,
825
- source: {
826
- month: "01",
827
- year: Date.today.year.to_s.last(2),
828
- cc_type: "123",
829
- last_digits: "1111",
830
- name: "Credit Card"
831
- }
832
- }]
833
- }
834
- end
835
-
836
- context "with source" do
837
- it "creates a payment" do
838
- post spree.api_orders_path, params: { order: params }
839
- payment = json_response['payments'].first
840
-
841
- expect(response.status).to eq 201
842
- expect(payment['amount']).to eql "10.0"
843
- expect(payment['source']['last_digits']).to eql "1111"
844
- end
845
-
846
- context "when payment_method is missing" do
847
- it "returns an error" do
848
- params[:payments][0].delete(:payment_method)
849
- post spree.api_orders_path, params: { order: params }
850
- expect(response.status).to eq 404
851
- end
852
- end
853
- end
854
- end
855
- end
856
-
857
- context "updating" do
858
- it "can set the user_id for the order" do
859
- user = Spree.user_class.create
860
- put spree.api_order_path(order), params: { order: { user_id: user.id } }
861
- expect(response.status).to eq 200
862
- expect(json_response["user_id"]).to eq(user.id)
863
- end
864
- end
865
-
866
- context "can cancel an order" do
867
- before do
868
- stub_spree_preferences(mails_from: "spree@example.com")
869
-
870
- order.completed_at = Time.current
871
- order.state = 'complete'
872
- order.shipment_state = 'ready'
873
- order.save!
874
- end
875
-
876
- specify do
877
- put spree.cancel_api_order_path(order)
878
- expect(json_response["state"]).to eq("canceled")
879
- expect(json_response["canceler_id"]).to eq(current_api_user.id)
880
- end
881
- end
882
- end
883
-
884
- describe '#apply_coupon_code' do
885
- let(:promo) { create(:promotion_with_item_adjustment, code: 'abc') }
886
- let(:promo_code) { promo.codes.first }
887
-
888
- before do
889
- allow_any_instance_of(Order).to receive_messages user: current_api_user
890
- end
891
-
892
- context 'when successful' do
893
- let(:order) { create(:order_with_line_items) }
894
-
895
- it 'applies the coupon' do
896
- expect(Spree::Deprecation).to receive(:warn)
897
-
898
- put spree.apply_coupon_code_api_order_path(order), params: { coupon_code: promo_code.value }
899
-
900
- expect(response.status).to eq 200
901
- expect(order.reload.promotions).to eq [promo]
902
- expect(json_response).to eq({
903
- "success" => I18n.t('spree.coupon_code_applied'),
904
- "error" => nil,
905
- "successful" => true,
906
- "status_code" => "coupon_code_applied"
907
- })
908
- end
909
- end
910
-
911
- context 'when unsuccessful' do
912
- let(:order) { create(:order) } # no line items to apply the code to
913
-
914
- it 'returns an error' do
915
- expect(Spree::Deprecation).to receive(:warn)
916
-
917
- put spree.apply_coupon_code_api_order_path(order), params: { coupon_code: promo_code.value }
918
-
919
- expect(response.status).to eq 422
920
- expect(order.reload.promotions).to eq []
921
- expect(json_response).to eq({
922
- "success" => nil,
923
- "error" => I18n.t('spree.coupon_code_unknown_error'),
924
- "successful" => false,
925
- "status_code" => "coupon_code_unknown_error"
926
- })
927
- end
928
- end
929
- end
930
- end
931
- end