solidus_api 2.10.5 → 2.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/app/controllers/spree/api/addresses_controller.rb +1 -1
  4. data/app/controllers/spree/api/base_controller.rb +11 -3
  5. data/app/controllers/spree/api/checkouts_controller.rb +1 -11
  6. data/app/controllers/spree/api/countries_controller.rb +2 -2
  7. data/app/controllers/spree/api/credit_cards_controller.rb +2 -2
  8. data/app/controllers/spree/api/customer_returns_controller.rb +67 -0
  9. data/app/controllers/spree/api/images_controller.rb +4 -4
  10. data/app/controllers/spree/api/inventory_units_controller.rb +1 -1
  11. data/app/controllers/spree/api/option_types_controller.rb +3 -3
  12. data/app/controllers/spree/api/option_values_controller.rb +2 -2
  13. data/app/controllers/spree/api/orders_controller.rb +1 -1
  14. data/app/controllers/spree/api/payments_controller.rb +1 -1
  15. data/app/controllers/spree/api/product_properties_controller.rb +9 -14
  16. data/app/controllers/spree/api/promotions_controller.rb +3 -12
  17. data/app/controllers/spree/api/properties_controller.rb +3 -3
  18. data/app/controllers/spree/api/resource_controller.rb +2 -2
  19. data/app/controllers/spree/api/return_authorizations_controller.rb +3 -3
  20. data/app/controllers/spree/api/shipments_controller.rb +1 -1
  21. data/app/controllers/spree/api/states_controller.rb +3 -3
  22. data/app/controllers/spree/api/stock_items_controller.rb +2 -2
  23. data/app/controllers/spree/api/stock_locations_controller.rb +3 -3
  24. data/app/controllers/spree/api/stock_movements_controller.rb +3 -3
  25. data/app/controllers/spree/api/stores_controller.rb +3 -3
  26. data/app/controllers/spree/api/taxonomies_controller.rb +2 -2
  27. data/app/controllers/spree/api/taxons_controller.rb +4 -4
  28. data/app/controllers/spree/api/users_controller.rb +13 -0
  29. data/app/controllers/spree/api/variants_controller.rb +3 -3
  30. data/app/controllers/spree/api/zones_controller.rb +2 -2
  31. data/app/helpers/spree/api/api_helpers.rb +18 -5
  32. data/app/views/spree/api/customer_returns/index.json.jbuilder +6 -0
  33. data/app/views/spree/api/customer_returns/new.json.jbuilder +4 -0
  34. data/app/views/spree/api/customer_returns/show.json.jbuilder +3 -0
  35. data/app/views/spree/api/errors/could_not_transition.json.jbuilder +4 -0
  36. data/app/views/spree/api/orders/could_not_transition.json.jbuilder +5 -0
  37. data/config/locales/en.yml +2 -0
  38. data/config/routes.rb +6 -3
  39. data/lib/spree/api/testing_support/helpers.rb +1 -1
  40. data/openapi/authentication.md +9 -1
  41. data/openapi/checkout-flow.md +17 -4
  42. data/openapi/main.hub.yml +1 -1
  43. data/openapi/solidus-api.oas.yml +6753 -0
  44. data/solidus_api.gemspec +19 -19
  45. metadata +14 -114
  46. data/openapi/api.oas2.yml +0 -6108
  47. data/script/rails +0 -10
  48. data/spec/controllers/spree/api/base_controller_spec.rb +0 -118
  49. data/spec/controllers/spree/api/resource_controller_spec.rb +0 -190
  50. data/spec/features/checkout_spec.rb +0 -192
  51. data/spec/fixtures/thinking-cat.jpg +0 -0
  52. data/spec/lib/spree_api_responders_spec.rb +0 -10
  53. data/spec/models/spree/legacy_user_spec.rb +0 -103
  54. data/spec/requests/api/address_books_spec.rb +0 -240
  55. data/spec/requests/jbuilder_cache_spec.rb +0 -34
  56. data/spec/requests/ransackable_attributes_spec.rb +0 -79
  57. data/spec/requests/spree/api/addresses_controller_spec.rb +0 -57
  58. data/spec/requests/spree/api/checkouts_controller_spec.rb +0 -484
  59. data/spec/requests/spree/api/classifications_controller_spec.rb +0 -50
  60. data/spec/requests/spree/api/config_controller_spec.rb +0 -26
  61. data/spec/requests/spree/api/countries_controller_spec.rb +0 -48
  62. data/spec/requests/spree/api/coupon_codes_controller_spec.rb +0 -105
  63. data/spec/requests/spree/api/credit_cards_controller_spec.rb +0 -105
  64. data/spec/requests/spree/api/images_controller_spec.rb +0 -99
  65. data/spec/requests/spree/api/inventory_units_controller_spec.rb +0 -55
  66. data/spec/requests/spree/api/line_items_controller_spec.rb +0 -213
  67. data/spec/requests/spree/api/option_types_controller_spec.rb +0 -116
  68. data/spec/requests/spree/api/option_values_controller_spec.rb +0 -138
  69. data/spec/requests/spree/api/orders_controller_spec.rb +0 -954
  70. data/spec/requests/spree/api/payments_controller_spec.rb +0 -259
  71. data/spec/requests/spree/api/product_properties_controller_spec.rb +0 -114
  72. data/spec/requests/spree/api/products_controller_spec.rb +0 -422
  73. data/spec/requests/spree/api/promotion_application_spec.rb +0 -50
  74. data/spec/requests/spree/api/promotions_controller_spec.rb +0 -67
  75. data/spec/requests/spree/api/properties_controller_spec.rb +0 -102
  76. data/spec/requests/spree/api/return_authorizations_controller_spec.rb +0 -180
  77. data/spec/requests/spree/api/shipments_controller_spec.rb +0 -532
  78. data/spec/requests/spree/api/states_controller_spec.rb +0 -69
  79. data/spec/requests/spree/api/stock_items_controller_spec.rb +0 -311
  80. data/spec/requests/spree/api/stock_locations_controller_spec.rb +0 -170
  81. data/spec/requests/spree/api/stock_movements_controller_spec.rb +0 -81
  82. data/spec/requests/spree/api/store_credit_events_controller_spec.rb +0 -59
  83. data/spec/requests/spree/api/stores_controller_spec.rb +0 -134
  84. data/spec/requests/spree/api/taxonomies_controller_spec.rb +0 -114
  85. data/spec/requests/spree/api/taxons_controller_spec.rb +0 -217
  86. data/spec/requests/spree/api/unauthenticated_products_controller_spec.rb +0 -27
  87. data/spec/requests/spree/api/users_controller_spec.rb +0 -151
  88. data/spec/requests/spree/api/variants_controller_spec.rb +0 -340
  89. data/spec/requests/spree/api/zones_controller_spec.rb +0 -89
  90. data/spec/shared_examples/protect_product_actions.rb +0 -18
  91. data/spec/spec_helper.rb +0 -73
  92. data/spec/support/be_paginated_matcher.rb +0 -9
  93. data/spec/support/controller_hacks.rb +0 -43
  94. data/spec/support/database_cleaner.rb +0 -16
  95. data/spec/support/have_attributes_matcher.rb +0 -11
  96. data/spec/test_views/spree/api/widgets/_widget.json.jbuilder +0 -3
  97. data/spec/test_views/spree/api/widgets/index.json.jbuilder +0 -9
  98. data/spec/test_views/spree/api/widgets/new.json.jbuilder +0 -3
  99. data/spec/test_views/spree/api/widgets/show.json.jbuilder +0 -3
@@ -1,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