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
).
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With