mr_muscle
mr_muscle

Reputation: 2900

RSpec check of correct serialization - result wraps serialized in an array

I want to check if response from my endpoint is serialized correctly (I'm using Fast JSON API serializer). Here is my code:

endpoint

get do
  ::Journeys::JourneyListSerializer.new(Journey.where(is_deleted: false))
end

JourneyListSerializer:

module Journeys
  class JourneyListSerializer
    include FastJsonapi::ObjectSerializer

    attribute :content do |object|
      object.content_basic.dig('entity')
    end
  end
end

my specs:

let!(:journey) { create(:journey, :with_activities, content_basic: hash) }
let(:hash) {{ "environment": "master", "entity_type": "item", "event_type": "update", "entity": { "id": "5202043", "type": "item", "attributes": { "title": "New text" }}}}

it 'serializes journey with proper serializer' do
 call
 expect(JSON.parse(response.body)).to be_serialization_of(journey, with: ::Journeys::JourneyListSerializer)
end

be_serialization_of helper in support/matchers

def be_serialization_of(object, options)
  serializer = options.delete(:with)
  raise 'you need to pass a serializer' if serializer.nil?

  serialized = serializer.new(object, options).serializable_hash
  match(serialized.as_json.deep_symbolize_keys)
end

Whole specs gives me an error:

  1) API::V1::Journeys::Index when params are valid serializes journey with proper serializer
     Failure/Error: expect(JSON.parse(response.body)).to be_serialization_of(journey, with: ::Journeys::JourneyListSerializer)

       expected {"data"=>[{"attributes"=>{"content"=>{"attributes"=>{"title"=>"New text"}, "id"=>"5202043", "type"=>"item"}}, "id"=>"75", "type"=>"journey_list"}]} to match {:data=>{:id=>"75", :type=>"journey_list", :attributes=>{:content=>{:id=>"5202043", :type=>"item", :attributes=>{:title=>"New text"}}}}}
       Diff:
       @@ -1,2 +1,2 @@
       -:data => {:attributes=>{:content=>{:attributes=>{:title=>"New text"}, :id=>"5202043", :type=>"item"}}, :id=>"75", :type=>"journey_list"},
       +"data" => [{"attributes"=>{"content"=>{"attributes"=>{"title"=>"New text"}, "id"=>"5202043", "type"=>"item"}}, "id"=>"75", "type"=>"journey_list"}],

I don't know why the result is in array, how to avoid that? when I'm using this endpoint it serialized without array.

Upvotes: 0

Views: 366

Answers (1)

probablykabari
probablykabari

Reputation: 1389

You're testing two different types of input here. The controller is testing a list of Journey but your test is serializing just one. Your matcher is fine, you are just putting the wrong input.

get do
  // "where" always returns an array of journeys
  ::Journeys::JourneyListSerializer.new(Journey.where(is_deleted: false))
end

// "journey" in the test is just one object, so you need to pass an array in the test
expect(JSON.parse(response.body)).to be_serialization_of([journey], with: ::Journeys::JourneyListSerializer)

Upvotes: 1

Related Questions