9

Este es un problema con la recolección de las galletas en una especificación de controlador en el entorno siguiente:cookies no persisten en Rspec sobre raíles 3.1

  • rieles 3.1.0.rc4
  • rspec 2.6.0
  • rspec-carriles 2.6.1

que tienen un simple especificación de controlador que crea un usuario de fábrica, llama a una señal en el método que establece una cookie, y luego se pone a prueba para ver si el firmado en usuario puede acceder a una página. El problema es que todas las cookies parecen desaparecer entre la cookie de autenticación que se está configurando y la acción "show" que se llama en mi controlador.

Mi código funciona bien cuando se ejecuta en un navegador en el servidor de rails dev. El comportamiento aún más extraño al ejecutar la especificación es que todo lo establecido a pesar del hash de las cookies desaparece, pero todo lo establecido a través del hash de la sesión persiste. ¿Me falta algo sobre cómo funcionan las cookies cuando se usa rspec?

Spec código

it "should be successful" do 
    @user = Factory(:user) 
    test_sign_in @user 
    get :show, :id => @user 
    response.should be_success 
end 

Entra código

def sign_in(user, opts = {}) 
    if opts[:remember] == true 
    cookies.permanent[:auth_token] = user.auth_token 
    else 
    cookies[:auth_token] = user.auth_token 
    end 
    session[:foo] = "bar" 
    cookies["blah"] = "asdf" 
    self.current_user = user 
    #there are two items in the cookies collection and one in the session now 
end 

verificación Autenticación en el get: solicitud espectáculo falla aquí porque las cookies [: auth_token] es nula

def current_user 
#cookies collection is now empty but session collection still contains :foo = "bar"... why? 
@current_user ||= User.find_by_auth_token(cookies[:auth_token]) if cookies[:auth_token] 
end 

¿Este ¿un insecto? ¿Es algún tipo de comportamiento previsto que no entiendo? ¿Acabo de mirar algo obvio?

+0

me sale el mismo problema - He intentado muchas permutaciones y hurgando y no puedo hacer que esto funcione correctamente –

Respuesta

3

Se metió en el mismo problema. Intente usar @request.cookie_jar de sus pruebas.

+1

Eso podría funcionar, pero no parece correcto configurar la cookie de mi código de prueba, ya que hacerlo sería redundante (el código de inicio de sesión ya lo hace) y podría hacer que las pruebas pasen. a pesar de los errores en mi código de inicio de sesión. – Fignuts

7

Éste es cómo lo resolvió:

def sign_in(user) 
cookies.permanent.signed[:remember_token] = [user.id, user.salt] 
current_user = user 
@current_user = user 
end 

def sign_out 
current_user = nil 
@current_user = nil 
cookies.delete(:remember_token) 
end 

def signed_in? 
return !current_user.nil? 
end 

Por alguna razón usted tiene que fijar tanto @current_user y current_user para que funcione en Rspec. No estoy seguro por qué, pero me volvía completamente loco ya que funcionaba bien en el navegador.

+1

¡Holy Moly! Esto funcionó para mí. Estaba actualizando el tutorial de Michael Hartl (railstutorial.org) a Rails 3.1.3 y encontré el mismo problema y esto funcionó por completo. Gracias @mike. –

+0

No hay problema, lo obtuve del mismo tutorial :) @MichaelKMadison – mike

+0

Gracias @mike! eso funcionó después de estar atrapado aquí por bastante tiempo.pero ¿por qué se requieren ambos? – freethinker

2

Las líneas adicionales anteriores no son necesarias. Descubrí que simplemente llamando al self.current_user = user el método setter puede actualizar automáticamente la variable de instancia. Por alguna razón, llamarlo sin auto no llama al método setter.

Aquí está mi código sin las líneas adicionales:

def sign_in(user) 
    cookies.permanent.signed[:remember_token] = [user.id, user.salt] 
    self.current_user = user 
end 

def sign_out 
    cookies.delete(:remember_token) 
    self.current_user = nil 
end 

def current_user=(user) 
    @current_user = user 
end 

Todavía no sé por qué, tal vez un error de Rspec

+0

, tanto esta como la respuesta de mike funcionen, aunque es un poco más elegante – prusswan

+2

Si no usa 'self'. then current_user = es una asignación de variable local, no la invocación de método de current_user = –

+0

+1 para una solución más elegante –

Cuestiones relacionadas