Rails/Rspec Выполнять тесты с помощью HTTP-аутентификации
Здесь моя базовая аутентификация http в файле контроллера приложения (application_controller.rb)
before_filter :authenticate
protected
def authenticate
authenticate_or_request_with_http_basic do |username, password|
username == "username" && password == "password"
end
end
и тест по умолчанию для действия индекса моего домашнего контроллера (spec/controllers/home_controller_spec.rb)
require 'spec_helper'
describe HomeController do
describe "GET 'index'" do
it "should be successful" do
get 'index'
response.should be_success
end
end
Тест не запускается из-за метода проверки подлинности. Я мог бы прокомментировать "before_filter: authenticate", чтобы запустить их, но я хотел бы знать, есть ли способ заставить их работать с этим методом.
Спасибо!
Ответы
Ответ 1
Обновление: Мэтт Коннолли предоставил GIST, который также работает для запросов и спецификаций контроллера: http://gist.github.com/4158961
Другой способ сделать это, если у вас много тестов для запуска и не хотите включать его каждый раз (код DRYer):
Создать файл /spec/support/auth _helper.rb:
module AuthHelper
def http_login
user = 'username'
pw = 'password'
request.env['HTTP_AUTHORIZATION'] = ActionController::HttpAuthentication::Basic.encode_credentials(user,pw)
end
end
В вашем тестовом файле:
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
Кредит здесь
Ответ 2
Извините, я не искал достаточно, решение похоже на следующее:
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
Ответ 3
При использовании Rspec для тестирования API-интерфейсов Grape выполняется следующий синтаксис
post :create, {:entry => valid_attributes}, valid_session
где valid_session -
{'HTTP_AUTHORIZATION' => credentials}
и
credentials = ActionController::HttpAuthentication::Token.encode_credentials("test_access1")
Ответ 4
В некоторых ответах предлагается установить request.env
, который является небезопасным, потому что запрос может быть nil
, и вы получите private method env' called for nil:NilClass
, особенно когда запускаете одиночные тесты с помощью rspec -e
Правильный подход будет:
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
Ответ 5
Это отличные решения для спецификаций контроллера и запроса.
Для функциональных тестов с использованием Capybara, вот решение для работы с базой HTTP:
спецификации/поддержка/when_authenticated.rb
RSpec.shared_context 'When authenticated' do
background do
authenticate
end
def authenticate
if page.driver.browser.respond_to?(:authorize)
# When headless
page.driver.browser.authorize(username, password)
else
# When javascript test
visit "http://#{username}:#{password}@#{host}:#{port}/"
end
end
def username
# Your value here. Replace with string or config location
Rails.application.secrets.http_auth_username
end
def password
# Your value here. Replace with string or config location
Rails.application.secrets.http_auth_password
end
def host
Capybara.current_session.server.host
end
def port
Capybara.current_session.server.port
end
end
Затем в вашей спецификации:
feature 'User does something' do
include_context 'When authenticated'
# test examples
end