solidus_api 2.10.5 → 2.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/app/controllers/spree/api/addresses_controller.rb +1 -1
  4. data/app/controllers/spree/api/base_controller.rb +11 -3
  5. data/app/controllers/spree/api/checkouts_controller.rb +1 -11
  6. data/app/controllers/spree/api/countries_controller.rb +2 -2
  7. data/app/controllers/spree/api/credit_cards_controller.rb +2 -2
  8. data/app/controllers/spree/api/customer_returns_controller.rb +67 -0
  9. data/app/controllers/spree/api/images_controller.rb +4 -4
  10. data/app/controllers/spree/api/inventory_units_controller.rb +1 -1
  11. data/app/controllers/spree/api/option_types_controller.rb +3 -3
  12. data/app/controllers/spree/api/option_values_controller.rb +2 -2
  13. data/app/controllers/spree/api/orders_controller.rb +1 -1
  14. data/app/controllers/spree/api/payments_controller.rb +1 -1
  15. data/app/controllers/spree/api/product_properties_controller.rb +9 -14
  16. data/app/controllers/spree/api/promotions_controller.rb +3 -12
  17. data/app/controllers/spree/api/properties_controller.rb +3 -3
  18. data/app/controllers/spree/api/resource_controller.rb +2 -2
  19. data/app/controllers/spree/api/return_authorizations_controller.rb +3 -3
  20. data/app/controllers/spree/api/shipments_controller.rb +1 -1
  21. data/app/controllers/spree/api/states_controller.rb +3 -3
  22. data/app/controllers/spree/api/stock_items_controller.rb +2 -2
  23. data/app/controllers/spree/api/stock_locations_controller.rb +3 -3
  24. data/app/controllers/spree/api/stock_movements_controller.rb +3 -3
  25. data/app/controllers/spree/api/stores_controller.rb +3 -3
  26. data/app/controllers/spree/api/taxonomies_controller.rb +2 -2
  27. data/app/controllers/spree/api/taxons_controller.rb +4 -4
  28. data/app/controllers/spree/api/users_controller.rb +13 -0
  29. data/app/controllers/spree/api/variants_controller.rb +3 -3
  30. data/app/controllers/spree/api/zones_controller.rb +2 -2
  31. data/app/helpers/spree/api/api_helpers.rb +18 -5
  32. data/app/views/spree/api/customer_returns/index.json.jbuilder +6 -0
  33. data/app/views/spree/api/customer_returns/new.json.jbuilder +4 -0
  34. data/app/views/spree/api/customer_returns/show.json.jbuilder +3 -0
  35. data/app/views/spree/api/errors/could_not_transition.json.jbuilder +4 -0
  36. data/app/views/spree/api/orders/could_not_transition.json.jbuilder +5 -0
  37. data/config/locales/en.yml +2 -0
  38. data/config/routes.rb +6 -3
  39. data/lib/spree/api/testing_support/helpers.rb +1 -1
  40. data/openapi/authentication.md +9 -1
  41. data/openapi/checkout-flow.md +17 -4
  42. data/openapi/main.hub.yml +1 -1
  43. data/openapi/solidus-api.oas.yml +6753 -0
  44. data/solidus_api.gemspec +19 -19
  45. metadata +14 -114
  46. data/openapi/api.oas2.yml +0 -6108
  47. data/script/rails +0 -10
  48. data/spec/controllers/spree/api/base_controller_spec.rb +0 -118
  49. data/spec/controllers/spree/api/resource_controller_spec.rb +0 -190
  50. data/spec/features/checkout_spec.rb +0 -192
  51. data/spec/fixtures/thinking-cat.jpg +0 -0
  52. data/spec/lib/spree_api_responders_spec.rb +0 -10
  53. data/spec/models/spree/legacy_user_spec.rb +0 -103
  54. data/spec/requests/api/address_books_spec.rb +0 -240
  55. data/spec/requests/jbuilder_cache_spec.rb +0 -34
  56. data/spec/requests/ransackable_attributes_spec.rb +0 -79
  57. data/spec/requests/spree/api/addresses_controller_spec.rb +0 -57
  58. data/spec/requests/spree/api/checkouts_controller_spec.rb +0 -484
  59. data/spec/requests/spree/api/classifications_controller_spec.rb +0 -50
  60. data/spec/requests/spree/api/config_controller_spec.rb +0 -26
  61. data/spec/requests/spree/api/countries_controller_spec.rb +0 -48
  62. data/spec/requests/spree/api/coupon_codes_controller_spec.rb +0 -105
  63. data/spec/requests/spree/api/credit_cards_controller_spec.rb +0 -105
  64. data/spec/requests/spree/api/images_controller_spec.rb +0 -99
  65. data/spec/requests/spree/api/inventory_units_controller_spec.rb +0 -55
  66. data/spec/requests/spree/api/line_items_controller_spec.rb +0 -213
  67. data/spec/requests/spree/api/option_types_controller_spec.rb +0 -116
  68. data/spec/requests/spree/api/option_values_controller_spec.rb +0 -138
  69. data/spec/requests/spree/api/orders_controller_spec.rb +0 -954
  70. data/spec/requests/spree/api/payments_controller_spec.rb +0 -259
  71. data/spec/requests/spree/api/product_properties_controller_spec.rb +0 -114
  72. data/spec/requests/spree/api/products_controller_spec.rb +0 -422
  73. data/spec/requests/spree/api/promotion_application_spec.rb +0 -50
  74. data/spec/requests/spree/api/promotions_controller_spec.rb +0 -67
  75. data/spec/requests/spree/api/properties_controller_spec.rb +0 -102
  76. data/spec/requests/spree/api/return_authorizations_controller_spec.rb +0 -180
  77. data/spec/requests/spree/api/shipments_controller_spec.rb +0 -532
  78. data/spec/requests/spree/api/states_controller_spec.rb +0 -69
  79. data/spec/requests/spree/api/stock_items_controller_spec.rb +0 -311
  80. data/spec/requests/spree/api/stock_locations_controller_spec.rb +0 -170
  81. data/spec/requests/spree/api/stock_movements_controller_spec.rb +0 -81
  82. data/spec/requests/spree/api/store_credit_events_controller_spec.rb +0 -59
  83. data/spec/requests/spree/api/stores_controller_spec.rb +0 -134
  84. data/spec/requests/spree/api/taxonomies_controller_spec.rb +0 -114
  85. data/spec/requests/spree/api/taxons_controller_spec.rb +0 -217
  86. data/spec/requests/spree/api/unauthenticated_products_controller_spec.rb +0 -27
  87. data/spec/requests/spree/api/users_controller_spec.rb +0 -151
  88. data/spec/requests/spree/api/variants_controller_spec.rb +0 -340
  89. data/spec/requests/spree/api/zones_controller_spec.rb +0 -89
  90. data/spec/shared_examples/protect_product_actions.rb +0 -18
  91. data/spec/spec_helper.rb +0 -73
  92. data/spec/support/be_paginated_matcher.rb +0 -9
  93. data/spec/support/controller_hacks.rb +0 -43
  94. data/spec/support/database_cleaner.rb +0 -16
  95. data/spec/support/have_attributes_matcher.rb +0 -11
  96. data/spec/test_views/spree/api/widgets/_widget.json.jbuilder +0 -3
  97. data/spec/test_views/spree/api/widgets/index.json.jbuilder +0 -9
  98. data/spec/test_views/spree/api/widgets/new.json.jbuilder +0 -3
  99. data/spec/test_views/spree/api/widgets/show.json.jbuilder +0 -3
@@ -1,50 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- module Spree::Api
6
- describe OrdersController, type: :request do
7
- before do
8
- stub_authentication!
9
- end
10
-
11
- context "with an available promotion" do
12
- let!(:order) { create(:order_with_line_items, line_items_count: 1) }
13
- let!(:promotion) do
14
- promotion = create(:promotion, name: "10% off", code: "10off")
15
- calculator = Spree::Calculator::FlatPercentItemTotal.create(preferred_flat_percent: "10")
16
- action = Spree::Promotion::Actions::CreateItemAdjustments.create(calculator: calculator)
17
- promotion.actions << action
18
- promotion
19
- end
20
-
21
- it "can apply a coupon code to the order" do
22
- expect(order.total).to eq(110.00)
23
- post spree.api_order_coupon_codes_path(order), params: { coupon_code: "10off", order_token: order.guest_token }
24
- expect(response.status).to eq(200)
25
- expect(order.reload.total).to eq(109.00)
26
- expect(json_response["success"]).to eq("The coupon code was successfully applied to your order.")
27
- expect(json_response["error"]).to be_blank
28
- expect(json_response["successful"]).to be true
29
- expect(json_response["status_code"]).to eq("coupon_code_applied")
30
- end
31
-
32
- context "with an expired promotion" do
33
- before do
34
- promotion.starts_at = 2.weeks.ago
35
- promotion.expires_at = 1.week.ago
36
- promotion.save
37
- end
38
-
39
- it "fails to apply" do
40
- post spree.api_order_coupon_codes_path(order), params: { coupon_code: "10off", order_token: order.guest_token }
41
- expect(response.status).to eq(422)
42
- expect(json_response["success"]).to be_blank
43
- expect(json_response["error"]).to eq("The coupon code is expired")
44
- expect(json_response["successful"]).to be false
45
- expect(json_response["status_code"]).to eq("coupon_code_expired")
46
- end
47
- end
48
- end
49
- end
50
- end
@@ -1,67 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- module Spree
6
- describe Spree::Api::PromotionsController, type: :request do
7
- shared_examples "a JSON response" do
8
- it 'should be ok' do
9
- subject
10
- expect(response).to be_ok
11
- end
12
-
13
- it 'should return JSON' do
14
- subject
15
- payload = HashWithIndifferentAccess.new(JSON.parse(response.body))
16
- expect(payload).to_not be_nil
17
- Spree::Api::ApiHelpers.promotion_attributes.each do |attribute|
18
- expect(payload).to be_has_key(attribute)
19
- end
20
- end
21
- end
22
-
23
- before do
24
- stub_authentication!
25
- end
26
-
27
- let(:promotion) { create :promotion, code: '10off' }
28
-
29
- describe 'GET #show' do
30
- subject { get spree.api_promotion_path(id) }
31
-
32
- context 'when admin' do
33
- sign_in_as_admin!
34
-
35
- context 'when finding by id' do
36
- let(:id) { promotion.id }
37
-
38
- it_behaves_like "a JSON response"
39
- end
40
-
41
- context 'when finding by code' do
42
- let(:id) { promotion.codes.first.value }
43
-
44
- it_behaves_like "a JSON response"
45
- end
46
-
47
- context 'when id does not exist' do
48
- let(:id) { 'argh' }
49
-
50
- it 'should be 404' do
51
- subject
52
- expect(response.status).to eq(404)
53
- end
54
- end
55
- end
56
-
57
- context 'when non admin' do
58
- let(:id) { promotion.id }
59
-
60
- it 'should be unauthorized' do
61
- subject
62
- assert_unauthorized!
63
- end
64
- end
65
- end
66
- end
67
- end
@@ -1,102 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
- module Spree
5
- describe Spree::Api::PropertiesController, type: :request do
6
- let!(:property_1) { Property.create!(name: "foo", presentation: "Foo") }
7
- let!(:property_2) { Property.create!(name: "bar", presentation: "Bar") }
8
-
9
- let(:attributes) { [:id, :name, :presentation] }
10
-
11
- before do
12
- stub_authentication!
13
- end
14
-
15
- it "can see a list of all properties" do
16
- get spree.api_properties_path
17
- expect(json_response["properties"].count).to eq(2)
18
- expect(json_response["properties"].first).to have_attributes(attributes)
19
- end
20
-
21
- it "can control the page size through a parameter" do
22
- get spree.api_properties_path, params: { per_page: 1 }
23
- expect(json_response['properties'].count).to eq(1)
24
- expect(json_response['current_page']).to eq(1)
25
- expect(json_response['pages']).to eq(2)
26
- end
27
-
28
- it 'can query the results through a parameter' do
29
- get spree.api_properties_path, params: { q: { name_cont: 'ba' } }
30
- expect(json_response['count']).to eq(1)
31
- expect(json_response['properties'].first['presentation']).to eq property_2.presentation
32
- end
33
-
34
- it "retrieves a list of properties by id" do
35
- get spree.api_properties_path, params: { ids: [property_1.id] }
36
- expect(json_response["properties"].first).to have_attributes(attributes)
37
- expect(json_response["count"]).to eq(1)
38
- end
39
-
40
- it "retrieves a list of properties by ids string" do
41
- get spree.api_properties_path, params: { ids: [property_1.id, property_2.id].join(",") }
42
- expect(json_response["properties"].first).to have_attributes(attributes)
43
- expect(json_response["properties"][1]).to have_attributes(attributes)
44
- expect(json_response["count"]).to eq(2)
45
- end
46
-
47
- it "can see a single property" do
48
- get spree.api_property_path(property_1.id)
49
- expect(json_response).to have_attributes(attributes)
50
- end
51
-
52
- it "can see a property by name" do
53
- get spree.api_property_path(property_1.name)
54
- expect(json_response).to have_attributes(attributes)
55
- end
56
-
57
- it "can learn how to create a new property" do
58
- get spree.new_api_property_path
59
- expect(json_response["attributes"]).to eq(attributes.map(&:to_s))
60
- expect(json_response["required_attributes"]).to be_empty
61
- end
62
-
63
- it "cannot create a new property if not an admin" do
64
- post spree.api_properties_path, params: { property: { name: "My Property 3" } }
65
- assert_unauthorized!
66
- end
67
-
68
- it "cannot update a property" do
69
- put spree.api_property_path(property_1.name), params: { property: { presentation: "my value 456" } }
70
- assert_unauthorized!
71
- end
72
-
73
- it "cannot delete a property" do
74
- delete spree.api_property_path(property_1.name)
75
- assert_unauthorized!
76
- expect { property_1.reload }.not_to raise_error
77
- end
78
-
79
- context "as an admin" do
80
- sign_in_as_admin!
81
-
82
- it "can create a new property" do
83
- expect(Spree::Property.count).to eq(2)
84
- post spree.api_properties_path, params: { property: { name: "My Property 3", presentation: "my value 3" } }
85
- expect(json_response).to have_attributes(attributes)
86
- expect(response.status).to eq(201)
87
- expect(Spree::Property.count).to eq(3)
88
- end
89
-
90
- it "can update a property" do
91
- put spree.api_property_path(property_1.name), params: { property: { presentation: "my value 456" } }
92
- expect(response.status).to eq(200)
93
- end
94
-
95
- it "can delete a property" do
96
- delete spree.api_property_path(property_1.name)
97
- expect(response.status).to eq(204)
98
- expect { property_1.reload }.to raise_error(ActiveRecord::RecordNotFound)
99
- end
100
- end
101
- end
102
- end
@@ -1,180 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- module Spree
6
- describe Api::ReturnAuthorizationsController, type: :request do
7
- let!(:order) { create(:shipped_order) }
8
-
9
- let(:product) { create(:product) }
10
- let(:attributes) { [:id, :memo, :state] }
11
-
12
- before do
13
- stub_authentication!
14
- end
15
-
16
- shared_examples_for 'a return authorization creator' do
17
- it "can create a new return authorization" do
18
- stock_location = FactoryBot.create(:stock_location)
19
- reason = FactoryBot.create(:return_reason)
20
- reimbursement = FactoryBot.create(:reimbursement_type)
21
- unit = FactoryBot.create(:inventory_unit)
22
- rma_params = { stock_location_id: stock_location.id,
23
- return_reason_id: reason.id,
24
- return_items_attributes: [{
25
- inventory_unit_id: unit.id,
26
- preferred_reimbursement_type_id: reimbursement.id,
27
- }],
28
- memo: "Defective" }
29
- post spree.api_order_return_authorizations_path(order), params: { order_id: order.number, return_authorization: rma_params }
30
- expect(response.status).to eq(201)
31
- expect(json_response).to have_attributes(attributes)
32
- expect(json_response["state"]).not_to be_blank
33
- return_authorization = Spree::ReturnAuthorization.last
34
- expect(return_authorization.return_items.first.preferred_reimbursement_type).to eql reimbursement
35
- end
36
- end
37
-
38
- context "as the order owner" do
39
- before do
40
- allow_any_instance_of(Order).to receive_messages user: current_api_user
41
- end
42
-
43
- it "cannot see any return authorizations" do
44
- get spree.api_order_return_authorizations_path(order)
45
- assert_unauthorized!
46
- end
47
-
48
- it "cannot see a single return authorization" do
49
- get spree.api_order_return_authorization_path(order, 1)
50
- assert_unauthorized!
51
- end
52
-
53
- it "cannot learn how to create a new return authorization" do
54
- get spree.new_api_order_return_authorization_path(order)
55
- assert_unauthorized!
56
- end
57
-
58
- it_behaves_like "a return authorization creator"
59
-
60
- it "cannot update a return authorization" do
61
- put spree.api_order_return_authorization_path(order, 0)
62
- assert_not_found!
63
- end
64
-
65
- it "cannot delete a return authorization" do
66
- delete spree.api_order_return_authorization_path(order, 0)
67
- assert_not_found!
68
- end
69
- end
70
-
71
- context "as another non-admin user that's not the order's owner" do
72
- before do
73
- allow_any_instance_of(Order).to receive_messages user: create(:user)
74
- end
75
-
76
- it "cannot create a new return authorization" do
77
- post spree.api_order_return_authorizations_path(order)
78
- assert_unauthorized!
79
- end
80
- end
81
-
82
- context "as an admin" do
83
- sign_in_as_admin!
84
-
85
- it "can show return authorization" do
86
- FactoryBot.create(:return_authorization, order: order)
87
- return_authorization = order.return_authorizations.first
88
- get spree.api_order_return_authorization_path(order, return_authorization.id)
89
- expect(response.status).to eq(200)
90
- expect(json_response).to have_attributes(attributes)
91
- expect(json_response["state"]).not_to be_blank
92
- end
93
-
94
- it "can get a list of return authorizations" do
95
- FactoryBot.create(:return_authorization, order: order)
96
- FactoryBot.create(:return_authorization, order: order)
97
- get spree.api_order_return_authorizations_path(order), params: { order_id: order.number }
98
- expect(response.status).to eq(200)
99
- return_authorizations = json_response["return_authorizations"]
100
- expect(return_authorizations.first).to have_attributes(attributes)
101
- expect(return_authorizations.first).not_to eq(return_authorizations.last)
102
- end
103
-
104
- it 'can control the page size through a parameter' do
105
- FactoryBot.create(:return_authorization, order: order)
106
- FactoryBot.create(:return_authorization, order: order)
107
- get spree.api_order_return_authorizations_path(order), params: { order_id: order.number, per_page: 1 }
108
- expect(json_response['count']).to eq(1)
109
- expect(json_response['current_page']).to eq(1)
110
- expect(json_response['pages']).to eq(2)
111
- end
112
-
113
- it 'can query the results through a paramter' do
114
- FactoryBot.create(:return_authorization, order: order)
115
- expected_result = create(:return_authorization, memo: 'damaged')
116
- order.return_authorizations << expected_result
117
- get spree.api_order_return_authorizations_path(order), params: { q: { memo_cont: 'damaged' } }
118
- expect(json_response['count']).to eq(1)
119
- expect(json_response['return_authorizations'].first['memo']).to eq expected_result.memo
120
- end
121
-
122
- it "can learn how to create a new return authorization" do
123
- get spree.new_api_order_return_authorization_path(order)
124
- expect(json_response["attributes"]).to eq(["id", "number", "state", "order_id", "memo", "created_at", "updated_at"])
125
- required_attributes = json_response["required_attributes"]
126
- expect(required_attributes).to include("order")
127
- end
128
-
129
- it "can update a return authorization on the order" do
130
- FactoryBot.create(:return_authorization, order: order)
131
- return_authorization = order.return_authorizations.first
132
- put spree.api_order_return_authorization_path(order, return_authorization.id), params: { return_authorization: { memo: "ABC" } }
133
- expect(response.status).to eq(200)
134
- expect(json_response).to have_attributes(attributes)
135
- end
136
-
137
- it "can cancel a return authorization on the order" do
138
- FactoryBot.create(:new_return_authorization, order: order)
139
- return_authorization = order.return_authorizations.first
140
- expect(return_authorization.state).to eq("authorized")
141
- put spree.cancel_api_order_return_authorization_path(order, return_authorization.id)
142
- expect(response.status).to eq(200)
143
- expect(return_authorization.reload.state).to eq("canceled")
144
- end
145
-
146
- it "can delete a return authorization on the order" do
147
- FactoryBot.create(:return_authorization, order: order)
148
- return_authorization = order.return_authorizations.first
149
- delete spree.api_order_return_authorization_path(order, return_authorization.id)
150
- expect(response.status).to eq(204)
151
- expect { return_authorization.reload }.to raise_error(ActiveRecord::RecordNotFound)
152
- end
153
-
154
- it_behaves_like "a return authorization creator"
155
- end
156
-
157
- context "as just another user" do
158
- it "cannot add a return authorization to the order" do
159
- post spree.api_order_return_authorizations_path(order), params: { return_autorization: { order_id: order.number, memo: "Defective" } }
160
- assert_unauthorized!
161
- end
162
-
163
- it "cannot update a return authorization on the order" do
164
- FactoryBot.create(:return_authorization, order: order)
165
- return_authorization = order.return_authorizations.first
166
- put spree.api_order_return_authorization_path(order, return_authorization.id), params: { return_authorization: { memo: "ABC" } }
167
- assert_unauthorized!
168
- expect(return_authorization.reload.memo).not_to eq("ABC")
169
- end
170
-
171
- it "cannot delete a return authorization on the order" do
172
- FactoryBot.create(:return_authorization, order: order)
173
- return_authorization = order.return_authorizations.first
174
- delete spree.api_order_return_authorization_path(order, return_authorization.id)
175
- assert_unauthorized!
176
- expect { return_authorization.reload }.not_to raise_error
177
- end
178
- end
179
- end
180
- end
@@ -1,532 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- describe Spree::Api::ShipmentsController, type: :request do
6
- include ActiveSupport::Testing::TimeHelpers
7
-
8
- let!(:shipment) { create(:shipment, inventory_units: [build(:inventory_unit, shipment: nil)]) }
9
- let!(:attributes) { [:id, :tracking, :tracking_url, :number, :cost, :shipped_at, :stock_location_name, :order_id, :shipping_rates, :shipping_methods] }
10
-
11
- before do
12
- stub_authentication!
13
- end
14
-
15
- let!(:resource_scoping) { { id: shipment.to_param, shipment: { order_id: shipment.order.to_param } } }
16
-
17
- context "as a non-admin" do
18
- it "cannot make a shipment ready" do
19
- put spree.ready_api_shipment_path(shipment)
20
- assert_unauthorized!
21
- end
22
-
23
- it "cannot make a shipment shipped" do
24
- put spree.ship_api_shipment_path(shipment)
25
- assert_unauthorized!
26
- end
27
-
28
- it "cannot remove order contents from shipment" do
29
- put spree.remove_api_shipment_path(shipment)
30
- assert_unauthorized!
31
- end
32
-
33
- it "cannot add contents to the shipment" do
34
- put spree.add_api_shipment_path(shipment)
35
- assert_unauthorized!
36
- end
37
-
38
- it "cannot update the shipment" do
39
- put spree.api_shipment_path(shipment)
40
- assert_unauthorized!
41
- end
42
- end
43
-
44
- context "as an admin" do
45
- let!(:order) { shipment.order }
46
- let!(:stock_location) { create(:stock_location_with_items) }
47
- let!(:variant) { create(:variant) }
48
-
49
- sign_in_as_admin!
50
-
51
- # Start writing this spec a bit differently than before....
52
- describe 'POST #create' do
53
- let(:params) do
54
- {
55
- variant_id: stock_location.stock_items.first.variant.to_param,
56
- shipment: { order_id: order.number },
57
- stock_location_id: stock_location.to_param
58
- }
59
- end
60
-
61
- subject do
62
- post spree.api_shipments_path, params: params
63
- end
64
-
65
- [:variant_id, :stock_location_id].each do |field|
66
- context "when #{field} is missing" do
67
- before do
68
- params.delete(field)
69
- end
70
-
71
- it 'should return proper error' do
72
- subject
73
- expect(response.status).to eq(422)
74
- expect(json_response['exception']).to eq("param is missing or the value is empty: #{field}")
75
- end
76
- end
77
- end
78
-
79
- it 'should create a new shipment' do
80
- subject
81
- expect(response).to be_ok
82
- expect(json_response).to have_attributes(attributes)
83
- end
84
- end
85
-
86
- it 'can update a shipment' do
87
- params = {
88
- shipment: {
89
- stock_location_id: stock_location.to_param
90
- }
91
- }
92
-
93
- put spree.api_shipment_path(shipment), params: params
94
- expect(response.status).to eq(200)
95
- expect(json_response['stock_location_name']).to eq(stock_location.name)
96
- end
97
-
98
- it "can make a shipment ready" do
99
- allow_any_instance_of(Spree::Order).to receive_messages(paid?: true, complete?: true)
100
- put spree.ready_api_shipment_path(shipment)
101
- expect(json_response).to have_attributes(attributes)
102
- expect(json_response["state"]).to eq("ready")
103
- expect(shipment.reload.state).to eq("ready")
104
- end
105
-
106
- it "cannot make a shipment ready if the order is unpaid" do
107
- allow_any_instance_of(Spree::Order).to receive_messages(paid?: false)
108
- put spree.ready_api_shipment_path(shipment)
109
- expect(json_response["error"]).to eq("Cannot ready shipment.")
110
- expect(response.status).to eq(422)
111
- end
112
-
113
- context 'for completed orders' do
114
- let(:order) { create :completed_order_with_totals }
115
- let(:shipment) { order.shipments.first }
116
-
117
- it 'adds a variant to a shipment' do
118
- put spree.add_api_shipment_path(shipment), params: { variant_id: variant.to_param, quantity: 2 }
119
- expect(response.status).to eq(200)
120
- expect(json_response['manifest'].detect { |h| h['variant']['id'] == variant.id }["quantity"]).to eq(2)
121
- end
122
-
123
- it 'removes a variant from a shipment' do
124
- order.contents.add(variant, 2)
125
-
126
- put spree.remove_api_shipment_path(shipment), params: { variant_id: variant.to_param, quantity: 1 }
127
- expect(response.status).to eq(200)
128
- expect(json_response['manifest'].detect { |h| h['variant']['id'] == variant.id }["quantity"]).to eq(1)
129
- end
130
-
131
- it 'removes a destroyed variant from a shipment' do
132
- order.contents.add(variant, 2)
133
- variant.discard
134
-
135
- put spree.remove_api_shipment_path(shipment), params: { variant_id: variant.to_param, quantity: 1 }
136
- expect(response.status).to eq(200)
137
- expect(json_response['manifest'].detect { |h| h['variant']['id'] == variant.id }["quantity"]).to eq(1)
138
- end
139
- end
140
-
141
- context 'for ready shipments' do
142
- let(:order) { create :order_ready_to_ship, line_items_attributes: [{ variant: variant, quantity: 1 }] }
143
- let(:shipment) { order.shipments.first }
144
-
145
- it 'adds a variant to a shipment' do
146
- put spree.add_api_shipment_path(shipment), params: { variant_id: variant.to_param, quantity: 1 }
147
- expect(response.status).to eq(200)
148
- expect(json_response['manifest'].detect { |h| h['variant']['id'] == variant.id }['quantity']).to eq(2)
149
- end
150
-
151
- it 'removes a variant from a shipment' do
152
- put spree.remove_api_shipment_path(shipment), params: { variant_id: variant.to_param, quantity: 1 }
153
- expect(response.status).to eq(200)
154
- expect(json_response['manifest'].detect { |h| h['variant']['id'] == variant.id }).to be nil
155
- end
156
- end
157
-
158
- context "for shipped shipments" do
159
- let(:order) { create :shipped_order }
160
- let(:shipment) { order.shipments.first }
161
-
162
- it 'adds a variant to a shipment' do
163
- put spree.add_api_shipment_path(shipment), params: { variant_id: variant.to_param, quantity: 2 }
164
- expect(response.status).to eq(200)
165
- expect(json_response['manifest'].detect { |h| h['variant']['id'] == variant.id }["quantity"]).to eq(2)
166
- end
167
-
168
- it 'cannot remove a variant from a shipment' do
169
- put spree.remove_api_shipment_path(shipment), params: { variant_id: variant.to_param, quantity: 1 }
170
- expect(response.status).to eq(422)
171
- expect(json_response['errors']['base'].join).to match /Cannot remove items/
172
- end
173
- end
174
-
175
- describe '#mine' do
176
- subject do
177
- get spree.mine_api_shipments_path, params: params
178
- end
179
-
180
- let(:params) { {} }
181
-
182
- context "the current api user is authenticated and has orders" do
183
- let(:current_api_user) { shipped_order.user }
184
- let!(:shipped_order) { create(:shipped_order) }
185
-
186
- it 'succeeds' do
187
- subject
188
- expect(response.status).to eq 200
189
- end
190
-
191
- describe 'json output' do
192
- let(:rendered_shipment_ids) { json_response['shipments'].map { |s| s['id'] } }
193
-
194
- it 'contains the shipments' do
195
- subject
196
- expect(rendered_shipment_ids).to match_array current_api_user.orders.flat_map(&:shipments).map(&:id)
197
- end
198
-
199
- context "credit card payment" do
200
- before { subject }
201
-
202
- it 'contains the id and cc_type of the credit card' do
203
- expect(json_response['shipments'][0]['order']['payments'][0]['source'].keys).to match_array ["id", "cc_type"]
204
- end
205
- end
206
-
207
- context "store credit payment" do
208
- let(:current_api_user) { shipped_order.user }
209
- let(:shipped_order) { create(:shipped_order, payment_type: :store_credit_payment) }
210
-
211
- before { subject }
212
-
213
- it 'only contains the id of the payment source' do
214
- expect(json_response['shipments'][0]['order']['payments'][0]['source'].keys).to match_array ["id"]
215
- end
216
- end
217
-
218
- context "check payment" do
219
- let(:current_api_user) { shipped_order.user }
220
- let(:shipped_order) { create(:shipped_order, payment_type: :check_payment) }
221
-
222
- before { subject }
223
-
224
- it 'does not try to render a nil source' do
225
- expect(json_response['shipments'][0]['order']['payments'][0]['source']).to eq(nil)
226
- end
227
- end
228
- end
229
-
230
- context 'with filtering' do
231
- let(:params) { { q: { order_completed_at_not_null: 1 } } }
232
-
233
- let!(:incomplete_order) { create(:order_with_line_items, user: current_api_user) }
234
-
235
- it 'filters' do
236
- subject
237
- expect(assigns(:shipments).map(&:id)).to match_array current_api_user.orders.complete.flat_map(&:shipments).map(&:id)
238
- end
239
- end
240
- end
241
-
242
- context "the current api user does not exist" do
243
- let(:current_api_user) { nil }
244
-
245
- it "returns a 401" do
246
- subject
247
- expect(response.status).to eq(401)
248
- end
249
- end
250
- end
251
- end
252
-
253
- describe "#estimated_rates" do
254
- let!(:user_shipping_method) { shipment.shipping_method }
255
- let!(:admin_shipping_method) { create(:shipping_method, available_to_users: false, name: "Secret") }
256
-
257
- sign_in_as_admin!
258
-
259
- subject do
260
- get spree.estimated_rates_api_shipment_path(shipment)
261
- end
262
-
263
- it "returns success" do
264
- subject
265
- expect(response).to be_successful
266
- end
267
-
268
- it "returns rates available to user" do
269
- subject
270
- expect(json_response['shipping_rates']).to include(
271
- {
272
- "name" => user_shipping_method.name,
273
- "cost" => "100.0",
274
- "shipping_method_id" => user_shipping_method.id,
275
- "shipping_method_code" => user_shipping_method.code,
276
- "display_cost" => "$100.00"
277
- }
278
- )
279
- end
280
-
281
- it "returns rates available to admin" do
282
- subject
283
- expect(json_response['shipping_rates']).to include(
284
- {
285
- "name" => admin_shipping_method.name,
286
- "cost" => "10.0",
287
- "shipping_method_id" => admin_shipping_method.id,
288
- "shipping_method_code" => admin_shipping_method.code,
289
- "display_cost" => "$10.00"
290
- }
291
- )
292
- end
293
- end
294
-
295
- describe "#ship" do
296
- let(:shipment) { create(:order_ready_to_ship).shipments.first }
297
-
298
- let(:send_mailer) { nil }
299
-
300
- subject do
301
- put spree.ship_api_shipment_path(shipment), params: { send_mailer: send_mailer }
302
- end
303
-
304
- context "the user is allowed to ship the shipment" do
305
- sign_in_as_admin!
306
- it "ships the shipment" do
307
- now = Time.current
308
- travel_to(now) do
309
- subject
310
- shipment.reload
311
- expect(shipment.state).to eq 'shipped'
312
- expect(shipment.shipped_at.to_i).to eq now.to_i
313
- end
314
- end
315
-
316
- describe 'sent emails' do
317
- subject { perform_enqueued_jobs { super() } }
318
-
319
- context "send_mailer not present" do
320
- it "sends the shipped shipments mailer" do
321
- expect { subject }.to change { ActionMailer::Base.deliveries.size }.by(1)
322
- expect(ActionMailer::Base.deliveries.last.subject).to match /Shipment Notification/
323
- end
324
- end
325
-
326
- context "send_mailer set to false" do
327
- let(:send_mailer) { 'false' }
328
- it "does not send the shipped shipments mailer" do
329
- expect { subject }.to_not change { ActionMailer::Base.deliveries.size }
330
- end
331
- end
332
-
333
- context "send_mailer set to true" do
334
- let(:send_mailer) { 'true' }
335
- it "sends the shipped shipments mailer" do
336
- expect { subject }.to change { ActionMailer::Base.deliveries.size }.by(1)
337
- expect(ActionMailer::Base.deliveries.last.subject).to match /Shipment Notification/
338
- end
339
- end
340
- end
341
- end
342
-
343
- context "the user is not allowed to ship the shipment" do
344
- sign_in_as_admin!
345
-
346
- before do
347
- ability = Spree::Ability.new(current_api_user)
348
- ability.cannot :ship, Spree::Shipment
349
- allow_any_instance_of(Spree::Api::ShipmentsController).to receive(:current_ability) { ability }
350
- end
351
-
352
- it "does nothing" do
353
- expect {
354
- expect {
355
- subject
356
- }.not_to change(shipment, :state)
357
- }.not_to change(shipment, :shipped_at)
358
- end
359
-
360
- it "responds with a 401" do
361
- subject
362
- expect(response.status).to eq 401
363
- end
364
- end
365
-
366
- context "the user is not allowed to view the shipment" do
367
- it "does nothing" do
368
- expect {
369
- expect {
370
- subject
371
- }.not_to change(shipment, :state)
372
- }.not_to change(shipment, :shipped_at)
373
- end
374
-
375
- it "responds with a 401" do
376
- subject
377
- expect(response).to be_unauthorized
378
- end
379
- end
380
- end
381
-
382
- describe "transfers" do
383
- let(:user) { create(:admin_user, spree_api_key: 'abc123') }
384
- let(:current_api_user) { user }
385
- let(:stock_item) { create(:stock_item, backorderable: false) }
386
- let(:variant) { stock_item.variant }
387
-
388
- let(:order) do
389
- create(
390
- :completed_order_with_totals,
391
- user: user,
392
- line_items_attributes: [
393
- {
394
- variant: variant
395
- }
396
- ]
397
- )
398
- end
399
-
400
- let(:shipment) { order.shipments.first }
401
-
402
- describe "POST /api/shipments/transfer_to_location" do
403
- let(:stock_location) { create(:stock_location) }
404
- let(:source_shipment) { order.shipments.first }
405
- let(:parsed_response) { JSON.parse(response.body) }
406
- let(:stock_location_id) { stock_location.id }
407
-
408
- subject do
409
- post "/api/shipments/transfer_to_location.json",
410
- params: {
411
- original_shipment_number: source_shipment.number,
412
- stock_location_id: stock_location_id,
413
- quantity: 1,
414
- variant_id: variant.id,
415
- token: user.spree_api_key
416
- }
417
- end
418
-
419
- context "for a successful transfer" do
420
- before do
421
- stock_location.restock(variant, 1)
422
- end
423
-
424
- it "returns the correct message" do
425
- subject
426
- expect(response).to be_successful
427
- expect(parsed_response["success"]).to be true
428
- expect(parsed_response["message"]).to eq("Variants successfully transferred")
429
- end
430
- end
431
-
432
- context "for an unsuccessful transfer" do
433
- before do
434
- source_shipment
435
- variant
436
- stock_location.stock_items.update_all(backorderable: false)
437
- end
438
-
439
- it "returns the correct message" do
440
- subject
441
- expect(response).to be_accepted
442
- expect(parsed_response["success"]).to be false
443
- expect(parsed_response["message"]).to eq("Desired shipment not enough stock in desired stock location")
444
- end
445
- end
446
-
447
- context "if the source shipment can not be found" do
448
- let(:stock_location_id) { 9999 }
449
-
450
- it "returns a 404" do
451
- subject
452
- expect(response).to be_not_found
453
- expect(parsed_response["error"]).to eq("The resource you were looking for could not be found.")
454
- end
455
- end
456
-
457
- context "if the user can not update shipments" do
458
- let(:user) { create(:user, spree_api_key: 'abc123') }
459
-
460
- custom_authorization! do |_|
461
- can :read, Spree::Shipment
462
- cannot :update, Spree::Shipment
463
- can :create, Spree::Shipment
464
- can :destroy, Spree::Shipment
465
- end
466
-
467
- it "is not authorized" do
468
- subject
469
- expect(response).to be_unauthorized
470
- end
471
- end
472
-
473
- context "if the user can not destroy shipments" do
474
- let(:user) { create(:user, spree_api_key: 'abc123') }
475
-
476
- custom_authorization! do |_|
477
- can :read, Spree::Shipment
478
- can :update, Spree::Shipment
479
- cannot :destroy, Spree::Shipment
480
- can :create, Spree::Shipment
481
- end
482
-
483
- it "is not authorized" do
484
- subject
485
- expect(response).to be_unauthorized
486
- end
487
- end
488
- end
489
-
490
- describe "POST /api/shipments/transfer_to_shipment" do
491
- let(:stock_location) { create(:stock_location) }
492
- let(:source_shipment) { order.shipments.first }
493
- let(:target_shipment) { order.shipments.create(stock_location: stock_location) }
494
- let(:parsed_response) { JSON.parse(response.body) }
495
- let(:source_shipment_number) { source_shipment.number }
496
-
497
- subject do
498
- post "/api/shipments/transfer_to_shipment.json",
499
- params: {
500
- original_shipment_number: source_shipment_number,
501
- target_shipment_number: target_shipment.number,
502
- quantity: 1,
503
- variant_id: variant.id,
504
- token: user.spree_api_key
505
- }
506
- end
507
-
508
- context "for a successful transfer" do
509
- before do
510
- stock_location.restock(variant, 1)
511
- end
512
-
513
- it "returns the correct message" do
514
- subject
515
- expect(response).to be_accepted
516
- expect(parsed_response["success"]).to be true
517
- expect(parsed_response["message"]).to eq("Variants successfully transferred")
518
- end
519
- end
520
-
521
- context "if the source shipment can not be found" do
522
- let(:source_shipment_number) { 9999 }
523
-
524
- it "returns a 404" do
525
- subject
526
- expect(response).to be_not_found
527
- expect(parsed_response["error"]).to eq("The resource you were looking for could not be found.")
528
- end
529
- end
530
- end
531
- end
532
- end