Sebastian Roth
Sebastian Roth

Reputation: 11537

Sending custom headers through RSpec

Given my API consumers are required to send a customer HTTP header like this:

# curl -H 'X-SomeHeader: 123' http://127.0.0.1:3000/api/api_call.json

Then I can read this header in a before_filter method like this:

# app/controllers/api_controller.rb
class ApiController < ApplicationController
    before_filter :log_request

private
    def log_request
        logger.debug "Header: #{request.env['HTTP_X_SOMEHEADER']}"
        ...
    end
end

So far great. Now I would like to test this using RSpec as there is a change in behavior:

# spec/controllers/api_controller_spec.rb
describe ApiController do
    it "should process the header" do
        @request.env['HTTP_X_SOMEHEADER'] = '123'
        get :api_call
        ...
    end
end

However, the request received in ApiController will not be able to find the header variable.

When trying the same code with the HTTP_ACCEPT_LANGUAGE header, it will work. Are custom headers filtered somewhere?

PS: Some examples around the web use request instead of @request. While I'm not certain which one is correct as of the current Rails 3.2/RSpec 2.14 combination - both methods will not trigger the right behavior, BUT both work with HTTP_ACCEPT_LANGUAGE as well.

Upvotes: 20

Views: 16418

Answers (3)

Kelsey Hannan
Kelsey Hannan

Reputation: 2967

RSpec request specs changed in Rails 5 so that custom headers and params must now be defined using key-value hash arguments. E.g.:

Before in Rails 4:

it "creates a Widget and redirects to the Widget's page" do
  headers = { "CONTENT_TYPE" => "application/json" }
  post "/widgets", '{ "widget": { "name":"My Widget" } }', headers
  expect(response).to redirect_to(assigns(:widget))
end

Now for Rails 5:

it "creates a Widget and redirects to the Widget's page" do
  headers = { "CONTENT_TYPE" => "application/json" }
  post "/widgets", :params => '{ "widget": { "name":"My Widget" } }', :headers => headers
  expect(response).to redirect_to(assigns(:widget))
end

Upvotes: 7

alexey_the_cat
alexey_the_cat

Reputation: 1872

well, maybe too late for people but just to be lined up:

it 'should get profile when authorized' do
  user = FactoryGirl.create :user
  request.headers[EMAIL_TOKEN] = user.email
  request.headers[AUTH_TOKEN] = user.authentication_token
  get :profile
  response.should be success
end

just call request.headers with appropriate settings.

Upvotes: 25

Billy Chan
Billy Chan

Reputation: 24815

You can define it in get directly.

get :api_call, nil, {'HTTP_FOO'=>'BAR'}

I just verified it works in console.

Upvotes: 12

Related Questions