Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access to request object in request specs

How can I set the request headers before doing the request on a request spec?

I'm moving controller specs to request specs on my API using Rails. One thing I'm stuck on is that I have no access to a request object to allow the requests.

On my controller specs, I have access to a method I created which signs a specific user:

def sign_in(user)
  token = user.api_keys.first.token
  # note the request object being used in the next line
  request.env["HTTP_AUTHORIZATION"] = ActionController::HttpAuthentication::Token.encode_credentials(token)
end

This works fine on controller specs, I can safely do:

before { sign_in(user) }
it { post :endpoint, params }

But on a request spec, the request object is not available. If I try to:

before { sign_in(user) }
it { post "/api/endpoint", params }

I get request on my helper method as nil.

I know I could do:

it { post "/api/endpoint", {"HTTP_AUTHORIZATION" => ... } }

But this seems a lot of clutter in the spec, specially compared to a controller spec.

I've tried using ActionDispatch::TestRequest::DEFAULT_ENV as suggested by this answer, but it didn't work too (I get a 401).

like image 816
Pedro Nascimento Avatar asked Apr 03 '14 23:04

Pedro Nascimento


1 Answers

If you're not already using Rack::Test for this then you should be. Rack::Test is better suited than Capybara for testing API requests. It can be configured in your rspec/spec_helper.rb

RSpec.configure do |config|
  # ...
  config.include Rack::Test::Methods
end

When you're configured to use Rack::Test, you can set headers before the request like so:

it 'POST /api/enpoint authenticates successfully' do
  header 'Authorization', '...'
  post "/api/endpoint", params
  expect(last_response).to be_ok
end

This will be accessible in your controller as request.headers['HTTP_AUTHORIZATION'].

The source code for this method can be found here - https://github.com/brynary/rack-test/blob/master/lib/rack/test.rb#L127-L141

like image 89
Sam Avatar answered Oct 20 '22 00:10

Sam