Appending headers to Rspec controller tests
I was able to fix it by using @request.env
instead of @request.headers
like so:
describe ApplyController do
context 'when valid' do
let(:parameters) do
file = File.join File.dirname(__FILE__), '..', 'samples', 'Indeed.json'
JSON.parse(File.read file)
end
let(:signature) { 'GC02UVj0d4bqa5peNFHdPQAZ2BI=' }
it 'returns 200 ok if Request is valid' do
@request.env['X-Indeed-Signature'] = signature
post :indeed, parameters
expect(response.status).to eq 200
end
end
end
adding headers to a rspec get
Unfortunately, rspec doesn't allow to set request headers, so you'll need to workaround it like this:
it "returns albums" do
request.headers.merge!(authenticated_header("admin", "123"))
get "/index", params: {}
puts response.body
end
custom request headers in rspec controller test being passed as rack.session
I've been digging through the issue this morning as well. The problem comes from here http://apidock.com/rails/ActionController/TestProcess/process as the method signature looks like this (action, parameters = nil, session = nil, flash = nil, http_method = 'GET')
. This was quite unexpected to me and I'll keep looking though I'm not quite sure why it happens like this.
To get it working you could do
before do
request.headers['X-API-KEY'] = 'somekey'
end
This works, although not exactly what I wanted/expected from the get
method.
Set header in RSpec 3 request
Note: This answer is based on what you seem to be calling api_v1_session_path
with post
request to SessionsController
for every spec you're trying to run in your requests specs.
There are two ways to solve the issue I figured you have here.
Solution #1 - Either you create another helper method in your SessionHelper
or in some other helper file called support/requests_helper.rb(however you prefer). I'd create another helper in support/requests_helper.rb:
module RequestsHelper
def get_with_token(path, params={}, headers={})
headers.merge!('HTTP_ACCESS_TOKEN' => retrieve_access_token)
get path, params, headers
end
def post_with_token(path, params={}, headers={})
headers.merge!('HTTP_ACCESS_TOKEN' => retrieve_access_token)
post path, params, headers
end
# similarly for xhr..
end
then in rails_helper.rb:
# Include the sessions helper
config.include SessionHelper, type: :request
# Include the requests helper
config.include RequestsHelper, type: :request
change session_helper.rb:
# my_app/spec/support/session_helper.rb
module SessionHelper
def retrieve_access_token
post api_v1_session_path({email: 'test@example.com', password: 'poor_password'})
expect(response.response_code).to eq 201
expect(response.body).to match(/"access_token":".{20}"/)
parsed = JSON(response.body)
parsed['access_token']['access_token'] # return token here!!
end
end
Now, you can change your all requests specs like this:
describe Api::V1::PostsController do
context "index" do
it "retrieves the posts" do
get_with_token api_v1_posts_path
expect(response.body).to include('"posts":[]')
expect(response.response_code).to eq 200
end
it "requires a valid session key" do
get api_v1_posts_path
expect(response.body).to include('"error":"unauthenticated"')
expect(response.response_code).to eq 401
end
end
end
Solution #2 - Change specs/factories/access_token_factory.rb to:
FactoryGirl.define do
factory :access_token do
active true
end
# can be used when you want to test against expired access tokens:
factory :inactive_access_token do
active false
end
end
Now, change your all requests specs to use access_token
:
describe Api::V1::PostsController do
context "index" do
let(:access_token){ FactoryGirl.create(:access_token) }
it "retrieves the posts" do
# You will have to send HEADERS while making request like this:
get api_v1_posts_path, nil, { 'HTTP_ACCESS_TOKEN' => access_token.access_token }
expect(response.body).to include('"posts":[]')
expect(response.response_code).to eq 200
end
it "requires a valid session key" do
get api_v1_posts_path
expect(response.body).to include('"error":"unauthenticated"')
expect(response.response_code).to eq 401
end
end
end
I'd go with "Solution #1" as it removes a burden of making you remember to send HTTP_ACCESS_TOKEN
in headers every time you want to make such requests.
RSpec/rails not setting request headers
Switching from type :api to type :request gave me access to the request and response variables, which, before, I had to created variables myself to try access them.
When using type :api, I had access to last_response instead of response, because my type :api was including Rack::Test::Methods, which was messing up those variables (response and request), as according to this post.
When I switched to type :request, and was no longer importing Rack::Test::Methods, I was able to access request variable and saw that the desired headers were correctly added.
How do I set headers for an Rspec post?
request.headers['password'] = 'x'
is correct. In your controller, however, you should be inspecting request.headers
and not just headers
.
RSpec: setting request headers
Please try like this:
request.env['HTTP_FOO_HEADER'] = 'foo header'
Related Topics
A Selenium Webdriver Exception
How to Get Rspec to Run All Tests Nested Under a Folder
How to Remove All Elements That Satisfy a Condition in Array in Ruby
How to Create Temp Dir in Ruby
Why Does Date Exist in Ruby Before It Is Required
C1 or C2 Coverage Tool for Ruby
Iterate an Array, N Items at a Time
Ruby Mechanize Post with Header
Rails Custom Validation - Only One Record Can Be True
Ruby Find and Return Objects in an Array Based on an Attribute
Accessing One Controller Variable in Another Controller in Rails
How Does Ruby Handle Bytes/Binary
How to Enable Ssl for a Standalone Sinatra App
How to Get a Substring from Position N to the Last Char in Ruby
Difference Between As_JSON and To_JSON Method in Ruby