Reputation: 7765
I can't test POST requests against my jsonapi-resources
Rails 5.1 API. Rails does not seem to allow me to customize request content types, or is doing it wrong.
jsonapi-resources
version 0.9.0, edge Rails (I think it's 5.2 beta2)
So, this IntegrationTest code:
require 'test_helper'
class EventsControllerTest < ActionDispatch::IntegrationTest
setup do
@event = events(:one)
end
test 'should get index' do
get events_url, as: 'application/vnd.api+json'
assert_response :success
end
test 'should create event' do
assert_difference('Event.count') do
post events_url, params: {
data: {
type: 'events',
attributes: {
name: @event.name,
body: @event.body
}
}
},
as: :api_json
end
assert_response 201
end
end
...produces this error:
$ bin/rails test
...
Failure:
EventsControllerTest#test_should_create_event [/Users/aljabear/Projects/visualist/test/controllers/events_controller_test.rb:26]:
...
The GET request works fine. The POST request is borked. Printing out the @request.body after the POST request gives this clue:
{
"errors":[
{"title":"Bad Request",
"detail":"765: unexpected token at 'data[type]=events\u0026data[attributes][name]=Book+1\u0026data[attributes][body]=This+is+body+text.'",
"code":"400",
"status":"400"
}
]
}
So, clearly the :api_json
content type is not being respected by Rails;
I guess it's instead spitting out form URL encoded.
if I do this instead, and print the result:
...
as: :json,
headers: {
'Content-type': 'application/vnd.api+json',
}
...
I get the following, showing that jsonapi-resources
is behaving properly (just very strictly); when I use as: :json
, Rails correctly formats things as json
, just not when I do :api_json
.
{
"errors":[{
"title":"Not acceptable",
"detail":"All requests must use the 'application/vnd.api+json' Accept without media type parameters. This request specified 'application/json'.",
"code":"406",
"status":"406"
}]
}
Is Rails just not bothering to convert the MIME type as requested? Or is this just a serialization issue? How can I force it to do it? Thanks... any clues are welcome.
Upvotes: 2
Views: 932
Reputation: 445
I'm successfully using code like the following:
test 'should create event' do
assert_difference('Event.count') do
post events_url, params: {
data: {
type: 'events',
attributes: {
name: @event.name,
body: @event.body
}
}
},
as: :json,
headers: {
'Accept' => JSONAPI::MEDIA_TYPE,
'Content-Type' => JSONAPI::MEDIA_TYPE
}
end
assert_response :created
end
I have a project on GitHub that you can look at to see my code.
Upvotes: 3
Reputation: 27747
Is Rails just not bothering to convert the MIME type as requested? Or is this just a serialization issue? How can I force it to do it?
tl;dr: Yes, yes and as_json
:)
tests are a subset of rails functionality - they don't go through the full rails stack (and thus does no conversions based on MIME type).
Yes, I think so - ie you need to serialize it so that rails can unserialize it.
Try running `as_json` on your data... eg
test 'should create event' do
assert_difference('Event.count') do
post events_url, params: {
data: {
type: 'events',
attributes: {
name: @event.name,
body: @event.body
}
}.as_json
},
as: :api_json
end
assert_response 201
end
or similar on your actual data... ie... if you're telling Rails to expect json... then pass it json? :D
Upvotes: 0