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.