Рельсы/тестирования RSpec сделать тесты с обычной проверкой подлинности http
здесь моя базовая аутентификация http в файле контроллера приложения (application_controller.РБ)
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.РБ)
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", чтобы запустить их, но я хотел бы знать, есть ли способ заставить их работать с этим методом.
спасибо!
5 ответов:
обновление (2013): Мэтт Коннолли предоставил суть, которая также работает для запроса и спецификаций контроллера:http://gist.github.com/4158961
другой способ сделать это, если у вас есть много тестов для запуска и не хотите включать его каждый раз (код сушилки):
создать /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
кредит здесь
Извините, что я не искал достаточно, решение, кажется, следующее:
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
при использовании Rspec для тестирования API Grape работает следующий синтаксис
post :create, {:entry => valid_attributes}, valid_session
где valid_session составляет
{'HTTP_AUTHORIZATION' => credentials}
и
credentials = ActionController::HttpAuthentication::Token.encode_credentials("test_access1")
некоторые ответы предлагают установить
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
эти большие решения для спецификаций регулятора и запроса.
для тестов функций с использованием Capybara, вот решение, чтобы сделать работу HTTP Basic authentication:
spec / support / when_authenticated.РБ
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