ruby-on-rails - tests - rspec rails 5
Rails/Rspec Hacer que las pruebas pasen con autenticación básica http (5)
Aquí mi autenticación básica http en el archivo del controlador de la aplicación (application_controller.rb)
before_filter :authenticate
protected
def authenticate
authenticate_or_request_with_http_basic do |username, password|
username == "username" && password == "password"
end
end
y la prueba predeterminada para la acción de índice de mi controlador doméstico (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
La prueba no se ejecuta debido al método de autenticación. Podría comentar "before_filter: authenticate" para ejecutarlos, pero me gustaría saber si hay alguna manera de hacer que funcionen con el método.
¡Gracias!
Algunas respuestas sugieren establecer request.env
que no es seguro, porque la solicitud puede ser nil
y terminará con private method env'' called for nil:NilClass
, especialmente cuando se ejecutan pruebas individuales con rspec -e
El enfoque correcto será:
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
Cuando se usa Rspec para probar API de uva, la siguiente sintaxis funciona
post :create, {:entry => valid_attributes}, valid_session
donde valid_session es
{''HTTP_AUTHORIZATION'' => credentials}
y
credentials = ActionController::HttpAuthentication::Token.encode_credentials("test_access1")
Estas son excelentes soluciones para controladores y especificaciones de solicitud.
Para las pruebas de características que usan Capybara, aquí hay una solución para hacer que la autenticación HTTP básica funcione:
spec / support / 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
Entonces, en tu especificación:
feature ''User does something'' do
include_context ''When authenticated''
# test examples
end
Lo siento, no busqué lo suficiente, la solución parece ser la siguiente:
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
Actualización : Matt Connolly ha proporcionado un GIST que también funciona para especificaciones de solicitud y controlador: http://gist.github.com/4158961
Otra forma de hacerlo es realizar muchas pruebas y no desea incluirlas cada vez (código DRYer):
Cree un archivo /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
En su archivo de especificaciones de prueba:
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
Crédito here