solidus_api 2.10.0 → 2.11.1

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