Skip to content

Commit 5e59c1c

Browse files
authored
fix(content-negotiation): correct 406 and 415 error mapping (#418)
Map invalid Content-Type requests to UnsupportedMediaType (415) and invalid Accept requests to UnacceptableMediaType (406). Update the spec compliance tests to assert the corrected statuses and JSON:API error codes/titles.
1 parent 5e8f0b1 commit 5e59c1c

4 files changed

Lines changed: 34 additions & 12 deletions

File tree

lib/ash_json_api/error/unacceptable_media_type.ex

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44

55
defmodule AshJsonApi.Error.UnacceptableMediaType do
66
@moduledoc """
7-
Returned when the client does not provide (via the `Content-Type` header) the correct json API media type: application/vnd.api+json
7+
Returned when the client does not accept (via the `Accept` header) the JSON:API
8+
media type: application/vnd.api+json
89
"""
910
use Splode.Error, class: :invalid
1011

lib/ash_json_api/error/unsupported_media_type.ex

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44

55
defmodule AshJsonApi.Error.UnsupportedMediaType do
66
@moduledoc """
7-
Returned when the client does not accept (via the `Accept` header) the json API media type: application/vnd.api+json
7+
Returned when the client does not provide (via the `Content-Type` header) the
8+
correct JSON:API media type: application/vnd.api+json
89
"""
910
use Splode.Error, class: :invalid
1011

lib/ash_json_api/request.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ defmodule AshJsonApi.Request do
277277
if any_content_type_supported? || json_api_content_type_supported? do
278278
request
279279
else
280-
add_error(request, UnacceptableMediaType.exception([]), request.route.type)
280+
add_error(request, UnsupportedMediaType.exception([]), request.route.type)
281281
end
282282
end
283283
end
@@ -314,7 +314,7 @@ defmodule AshJsonApi.Request do
314314
if accepts_json_api? do
315315
request
316316
else
317-
add_error(request, UnsupportedMediaType.exception([]), request.route.type)
317+
add_error(request, UnacceptableMediaType.exception([]), request.route.type)
318318
end
319319
end
320320

test/spec_compliance/content_negotiation_test.exs

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -204,11 +204,16 @@ defmodule AshJsonApi.ContentNegotiationTest do
204204

205205
@tag capture_log: true
206206
test "request Content-Type header includes two instances of JSON:API modified with a param" do
207-
post(Domain, "/posts", @create_body,
207+
Domain
208+
|> post("/posts", @create_body,
208209
req_content_type_header:
209210
"application/vnd.api+json; charset=test, application/vnd.api+json; charset=test",
210-
status: 406
211+
status: 415
211212
)
213+
|> assert_has_error(%{
214+
"code" => "unsupported_media_type",
215+
"title" => "Unsupported Media Type"
216+
})
212217
end
213218

214219
test "request Content-Type header is a random value" do
@@ -219,10 +224,15 @@ defmodule AshJsonApi.ContentNegotiationTest do
219224

220225
@tag capture_log: true
221226
test "request Content-Type header is a valid media type other than JSON:API" do
222-
post(Domain, "/posts", @create_body,
227+
Domain
228+
|> post("/posts", @create_body,
223229
req_content_type_header: "application/vnd.api+json; charset=\"utf-8\"",
224-
status: 406
230+
status: 415
225231
)
232+
|> assert_has_error(%{
233+
"code" => "unsupported_media_type",
234+
"title" => "Unsupported Media Type"
235+
})
226236
end
227237
end
228238

@@ -269,11 +279,16 @@ defmodule AshJsonApi.ContentNegotiationTest do
269279
test "request Accept header includes two instances of JSON:API modified with a param", %{
270280
post: post
271281
} do
272-
get(Domain, "/posts/#{post.id}",
282+
Domain
283+
|> get("/posts/#{post.id}",
273284
req_accept_header:
274285
"application/vnd.api+json; charset=test, application/vnd.api+json; charset=test",
275-
status: 415
286+
status: 406
276287
)
288+
|> assert_has_error(%{
289+
"code" => "unacceptable_media_type",
290+
"title" => "Unacceptable Media Type"
291+
})
277292
end
278293

279294
test "request Accept header is a random value", %{post: post} do
@@ -290,10 +305,15 @@ defmodule AshJsonApi.ContentNegotiationTest do
290305

291306
@tag capture_log: true
292307
test "request Accept header is a valid media type other than JSON:API", %{post: post} do
293-
get(Domain, "/posts/#{post.id}",
308+
Domain
309+
|> get("/posts/#{post.id}",
294310
req_accept_header: "application/vnd.api+json; charset=\"utf-8\"",
295-
status: 415
311+
status: 406
296312
)
313+
|> assert_has_error(%{
314+
"code" => "unacceptable_media_type",
315+
"title" => "Unacceptable Media Type"
316+
})
297317
end
298318

299319
test "request Accept header is a valid media type other than JSON:API with bypass config", %{

0 commit comments

Comments
 (0)