2011-03-08 23 views
8

Estoy tratando de escribir pruebas de integración con rspec, factory_girl & capybara. También tengo el pepino instalado, pero no lo estoy usando (que yo sepa).Probando sesiones en Rails 3 con Rspec & Capybara

Básicamente quiero rellenar el archivo db con mi usuario, luego ir a la página de inicio e intentar iniciar sesión. Debería redirigir a user_path (@user).

Sin embargo, las sesiones no parecen persistir en mis pruebas/rspec/requests/integration.

mi especificación: /rspec/requests/users_spec.rb

require 'spec_helper' 

describe "User flow" do 

    before(:each) do 
    @user = Factory(:user) 
    end 

    it "should login user" do 

    visit("/index") 

    fill_in :email, :with => @user.email 
    fill_in :password, :with => @user.password 
    click_button "Login" 
    assert current_path == user_path(@user) 
    end 
end 

Devuelve:

Failures: 

    1) User flow should login user 
    Failure/Error: assert current_path == user_path(@user) 
    <false> is not true. 
    # (eval):2:in `send' 
    # (eval):2:in `assert' 
    # ./spec/requests/users_spec.rb:16 

su lugar, se vuelve a dirigir a mi please_login_path - lo que debería ocurrir si el inicio de sesión falla por cualquier motivo (o si la sesión [: user_id] no está configurada).

Si intento poner session.inspect, falla como un objeto nulo.

Si trato de hacer esto en el controlador comprueba (/rspec/controllers/sessions_spec.rb), que se puede acceder a la sesión sin ningún problema, y ​​puedo llamar a sesión [: user_id]

+1

No sé si esto está relacionado, pero no debería poder obtener la contraseña de un usuario escribiendo @ user.password. Esta es una vulnerabilidad de seguridad en su aplicación. ¿Estás almacenando las contraseñas usando texto sin formato? –

+5

No está relacionado, y probablemente no sea una vulnerabilidad de seguridad. La llamada a # contraseña solo devuelve una contraseña porque está establecida en la variable de instancia por Fábrica. Es probable que esté usando Devise o algo similar que no persista en el atributo de contraseña para el db en texto claro, por lo que no estaría disponible si esa variable de instancia desapareciera. –

Respuesta

6

Si está usando Devise, necesitarás incluir Warden :: Test :: Helpers (justo después de que require de spec_helper es un buen lugar) como se describe en in the warden wiki.

La llamada a la sesión devuelve nil porque capybara no proporciona acceso a ella cuando se ejecuta como una prueba de integración.

1

Probablemente haya pasado de esto, pero yo estaba luchando con la misma pregunta. Resulta que era una cuestión de sintaxis. Estaba usando símbolos para :email y :password y debería haber estado usando cadenas en su lugar ("email" y "password").

En otras palabras, trate de cambiar esto:

fill_in :email, :with => @user.email 
fill_in :password, :with => @user.password 

a esto:

fill_in "email", :with => @user.email 
fill_in "password", :with => @user.password 
3

tengo los mismos problemas y aunque rellenar un formulario podría ser una opción para algunos, tuve que rodar mi propio rubí de autenticación porque estaba usando un sistema de autenticación de terceros (Janrain para ser exactos) .... en mis pruebas terminé usando algo como esto:

Esto es lo que tengo en mi especificación/soporte /test_helpers_and_stuff.rb

module AuthTestHelper 

    class SessionBackdoorController < ::ApplicationController 
    def create 
     sign_in User.find(params[:user_id]) 
     head :ok 
    end 
    end 

    begin 
    _routes = Rails.application.routes 
    _routes.disable_clear_and_finalize = true 
    _routes.clear! 
    Rails.application.routes_reloader.paths.each{ |path| load(path) } 
    _routes.draw do 
     # here you can add any route you want 
     match "/test_login_backdoor", to: "session_backdoor#create" 
    end 
    ActiveSupport.on_load(:action_controller) { _routes.finalize! } 
    ensure 
    _routes.disable_clear_and_finalize = false 
    end 

    def request_signin_as(user) 
    visit "/test_login_backdoor?user_id=#{user.id}" 
    end 

    def signin_as(user) 
    session[:session_user] = user.id 
    end 

end 

Luego, en mi especificación solicitud, la capibara y el selenio, hice lo siguiente:

describe "Giveaway Promotion" do 
    context "Story: A fan participates in a giveaway", js: :selenium do 
    context "as a signed in user" do 

     before :each do 
     @user = Factory(:user) 
     request_signin_as @user 
     end 

     it "should be able to participate as an already signed in user" do 
     visit giveaway_path 
     .... 
     end 
    end 
    end 
end 

Por cierto, se me ocurrió con las soluciones después de probar las soluciones propuestas a this post y this post y ninguno de ellos funcionó para mí. (pero ciertamente inspiraron mi solución)

¡Buena suerte!

Cuestiones relacionadas