I'm trying to setup RSpec tests for my Rails 5 API server. The server uses active_model_serializers (0.10.5)
with the JSON API adapter.
From what I can tell, the server is serving valid JSON:
{
"data": [{
"id": "1",
"type": "categories",
"attributes": {
"name": "Language"
}
}, {
"id": "2",
"type": "categories",
"attributes": {
"name": "Ruby"
}
}, {
"id": "3",
"type": "categories",
"attributes": {
"name": "HTML"
}
}]
}
Here is my setup:
app/controllers/categories_controller.rb
def index
@categories = Category.all
render json: @categories
end
app/serializers/category_serializer.rb
class CategorySerializer < ActiveModel::Serializer
attributes :id, :name
end
spec/requests/categories_spec.rb
describe 'GET /categories' do
before do
@category1 = FactoryGirl.create(:category)
@category2 = FactoryGirl.create(:category)
get '/categories'
json = ActiveModelSerializers::Deserialization.jsonapi_parse!(response.body)
@category_ids = json.collect { |category| category['id'] }
end
it 'returns all resources in the response body' do
expect(@category_ids).to eq([@category1.id, @category2.id])
end
it 'returns HTTP status ok' do
expect(response).to have_http_status(:ok)
end
end
Following is the error I get when running bundle exec spec
:
ActiveModelSerializers::Adapter::JsonApi::Deserialization::InvalidDocument:
Invalid payload (Expected hash): {"data":
[{"id":"55","type":"categories","attributes":{"name":"feed"}},
{"id":"56","type":"categories","attributes":{"name":"bus"}}]}
What am I missing to get the deserializer working?
You don't need to use the ActiveModel deserializer in this context. For your tests, just do something like this:
parsed_response = JSON.parse(response.body)
expect(parsed_response['data'].size).to eq(2)
expect(parsed_response['data'].map { |category| category['id'].to_i })
.to eq(Category.all.map(&:id))
expect(response.status).to eq(200)