5

I am writing some rspec for an API and trying to test HTTP request code directly in the rails console so I can see what I get back.

For example I have the following lines in my spec

      json_data = '{"user": {"email": "#{user.email}", "password": "#{user.password}"}}'
      post "api/v1/users/sign_in", json_data  
      @token = json(last_response)[:client][:auth_token]
      get 'api/v1/users', {}, {'Authorization' => @token}

This code doesn't work because my 'json()' function is not parsing the response correctly. I want to take those 'post' and 'get' with JSON arguments and test them in rails console with Net::HTTP so I can see what responses are being returned and debug my spec code. Anyone know how to do that?

In case it matter the authorization token I am trying to use is generated by Devise.

Count Zero
  • 630
  • 1
  • 6
  • 15

2 Answers2

3

To test your API endpoint via the rails console and Net::HTTP you would need to run following code in the console:

require "net/http"
require "uri"

uri = URI.parse("http://example.com/api/v1/users/sign_in")
user = User.find(..)

json_data = '{"user": {"email": "#{user.email}", "password": "#{user.password}"}}'

http = Net::HTTP.new(uri.host, uri.port)

request = Net::HTTP::Post.new(uri.request_uri, {'Content-Type' => 'application/json'})
request.set_form_data(JSON.parse(json_data))

response = http.request(request)
json(response.body)

But i would suggest that you use rspec request specs for this kind of testing. What is missing in your code is that you need to tell the server which content type is expected from your request so that rails can parse your request body accordingly (json / xml /etc.).

consider using:

post "api/v1/users/sign_in", json_data, {'Content-Type' => 'application/json', 'Accept' => 'application/json'}

Here is also a brief description of those request headers:

Content-Type: The Content-Type header field is used to specify the nature of the data in the body of an entity, by giving type and subtype identifiers

Accept: Is used to specify the response type which you want to receive back from the server.

So in short:

Content-Type --> Type of content you are sending to the server

Accept --> Type of content you want to receive from the server

Erwin Schens
  • 424
  • 2
  • 9
1

You need to tell rails that the data you are sending is JSON encoded.

post "api/v1/users/sign_in", json_data, format: :json

For an api you might want to set the default request format to JSON.

namespace :api, defaults: { format: 'json' } do
  namespace :v1 do
    # ...
  end
end
max
  • 96,212
  • 14
  • 104
  • 165
  • See also http://stackoverflow.com/questions/11022839/set-rspec-default-get-request-format-to-json for how to set default request format in controller specs. – max Jul 22 '15 at 01:50