Search code examples
ruby-on-railsjsonruby-on-rails-4strong-parameters

Trying to pull data from params object in Rails API using JSON


With Rspec, I am trying to build a spec testing some basic http requests. I'm making a rookie mistake somewhere and need help finding it.

I am purposely making the spec fail with a nonsense expectation so the error message will tell me what I'm getting -- once I figure things out I'll correct the expectation:

  user = create(:member)
  json_data = {email: user.email, password: user.password}.to_json
  post "api/v1/users/sign_in", json_data, format: :json
  expect(last_response.body).to eq "foobar"

api/v1/users/sign_in routes to the following controller:

class API::V1::SessionsController < Devise::SessionsController
  respond_to :json
  def create
    render text: params
  end
end

This gives the error:

expected: "foobar" got: "{\"{\\"email\\":\\"[email protected]\\",\\"password\\":\\"12345678\\"}\"=>nil, \"action\"=>\"create\", \"controller\"=>\"api/v1/sessions\"}"

Ok great. My data is getting to the server and the server sends it back, which is what I want. In my next step I try to grab the email. I change the controller to

class API::V1::SessionsController < Devise::SessionsController
   respond_to :json
   def create
      render text: params[:email]
    end
 end

and I get

expected: "foobar" got: " "

I looks to me that the params hash is using the JSOn data I sent in the request as the name of a key, not actually a value. Or maybe this is a strong_params thing? I've tried many things and can't seem to pull the data I want out of the params object.


Solution

  • What is happening is that you are double encoding the JSON data which you are sending in your spec.

    json_data = {email: user.email, password: user.password}
    post "api/v1/users/sign_in", json_data, format: :json
    

    RSpec will automatically encode the request body as JSON for you.