Rails/Rspec Make tests pass with http basic authentication
For me, with Rails 6, I need keyword arguments for rspec get method like .. get route, params: params, headers: headers
Auth Helper method
module AuthHelper
def headers(options = {})
user = ENV['BASIC_AUTH_USER']
pw = ENV['BASIC_AUTH_PASSWORD']
{ HTTP_AUTHORIZATION: ActionController::HttpAuthentication::Basic.encode_credentials(user,pw) }
end
def auth_get(route, params = {})
get route, params: params, headers: headers
end
end
and the rspec request test.
describe HomeController, type: :request do
include AuthHelper
describe "GET 'index'" do
it "should be successful" do
auth_get 'index'
expect(response).to be_successful
end
end
end
Sorry I didn't seek enough, the solution seems to be the following:
describe "GET 'index'" do
it "should be successful" do
@request.env["HTTP_AUTHORIZATION"] = "Basic " + Base64::encode64("username:password")
get 'index'
response.should be_success
end
end
Some answers suggest to set request.env
which is unsafe, because request can be nil
and you will end up with private method env' called for nil:NilClass
, especially when run single tests with rspec -e
Correct approach will be:
def http_login
user = 'user'
password = 'passw'
{
HTTP_AUTHORIZATION: ActionController::HttpAuthentication::Basic.encode_credentials(user,password)
}
end
get 'index', nil, http_login
post 'index', {data: 'post-data'}, http_login
Update (2013): Matt Connolly has provided a GIST which also works for request and controller specs: http://gist.github.com/4158961
Another way of doing this if you have many tests to run and don't want to include it everytime (DRYer code):
Create a /spec/support/auth_helper.rb file:
module AuthHelper
def http_login
user = 'username'
pw = 'password'
request.env['HTTP_AUTHORIZATION'] = ActionController::HttpAuthentication::Basic.encode_credentials(user,pw)
end
end
In your test spec file:
describe HomeController do
render_views
# login to http basic auth
include AuthHelper
before(:each) do
http_login
end
describe "GET 'index'" do
it "should be successful" do
get 'index'
response.should be_success
end
end
end
Credit here