Search code examples
rubyrspecsinatrarackrack-test

Why is an Array in my payload being flattened in Sinatra / Rack::Test?


I'm trying to test a small Sinatra app using rspec. I want to pass a rather complex payload and am running into issues i do not understand: my payload contains an array of hashes. When I run the actual application this will work as expected, yet when I use the post helper to run my tests, the array will contain a merged hash:

post(
  "/#{bot}/webhook",
  sessionId: "test-session-#{session_counter}",
  result: {
    contexts: [
      { some: 'fixture' },
      { name: 'generic', parameters: { facebook_sender_id: 'zuck-so-cool' } }
    ]
  }
)

In the sinatra handler I use params to access this payload:

post '/:bot/webhook' do |bot|
  do_something_with(params)
end

When I now look at the structure of params when running the test suite, I will see the following structure:

[{"some" => "fixture", "name" => "generic", "parameters" => {"facebook_sender_id" => "zuck-so-cool"}}]

which I do not really understand. Is this a syntax issue (me being a ruby noob), am I using params wrong, or is this a bug?

EDIT: So i found out this is an "issue" with the way that Rack::Test will serialize the given payload when not specifying how to (i.e. as form data). If I pass JSON and pass the correct headers it will do what I expect it to do:

post(
  "/#{bot}/webhook",
  {
      sessionId: "test-session-#{session_counter}",
      result: {
        contexts: [
          { some: 'fixture' },
          { name: 'generic', parameters: { facebook_sender_id: 'zuck-so-cool' } }
        ]
      }
  }.to_json,
  { 'HTTP_ACCEPT' => 'application/json', 'CONTENT_TYPE' => 'application/json' }
)

Still I am unsure of this is an issue with the passed data structure not being possible to be serialized into form data or if this is a bug in the way that Rack::Test serializes data.


Solution

  • Looking at the relevant portion of the specs it looks like this is is expected behavior.