2011-02-12 18 views
18

que tienen una acción de algún controlador que establece un valor en una cookie permanente firmado así:cómo probar cookies.permanent.signed en Rails 3

 

def some_action 
    cookies.permanent.signed[:cookie_name] = "somevalue" 
end 
 

Y de alguna prueba de funcionamiento, estoy tratando para probar si la cookie se estableció demandar correctamente esto:

 

test "test cookies" do 
    assert_equal "somevalue", cookies.permanent.signed[:cookie_name] 
end 

 

Sin embargo, cuando ejecuto la prueba, tengo el siguiente error:

 

NoMethodError: undefined method `permanent' for # 
 

Si sólo tratan:

 

test "test cookies" do 
    assert_equal "somevalue", cookies.signed[:cookie_name] 
end 

 

me sale:

 

NoMethodError: undefined method `signed' for # 
 

Cómo probar las galletas firmados en Rails 3?

Respuesta

2

El problema (al menos en la superficie) es que en el contexto de una prueba funcional (ActionController :: TestCase), el objeto "cookies" es un Hash, mientras que cuando trabajas con los controladores, es un ActionDispatch: : Cookies :: Objeto CookieJar. Entonces, necesitamos convertirlo en un objeto CookieJar para que podamos usar el método "signed" en él para convertirlo a SignedCookieJar.

Usted puede poner lo siguiente en sus pruebas de funcionamiento (después de una petición GET) para convertir las cookies de un hash a un objeto CookieJar

@request.cookies.merge!(cookies) 
cookies = ActionDispatch::Cookies::CookieJar.build(@request) 
+0

Tengo exactamente el mismo problema. Estoy usando la unidad de prueba. No entiendo cómo usar tu 2-liner. Intenté diferentes permutaciones pero nada funcionó. ¿Puedes dar un ejemplo más completo sobre cómo usar esto? – allesklar

8

En los carriles de 3 ActionControlller :: TestCase, se puede establecer firmado cookies permanentes en el objeto solicitud como tal -

@request.cookies.permanent.signed[:foo] = "bar" 

y las galletas firmados devueltos por una acción realizada en un controlador puede ser probado por hacer esto

test "do something" do 
    get :index # or whatever 
    jar = @request.cookie_jar 
    jar.signed[:foo] = "bar" 
    assert_equal jar[:foo], @response.cookies['foo'] #should both be some enc of 'bar' 
end 

Tenga en cuenta que tenemos que configurar la cookie firmada jar.signed[:foo], pero lea la cookie sin firmar jar[:foo]. Solo entonces obtenemos el valor encriptado de la cookie, necesario para comparar en assert_equal.

+0

¡Impresionante! Solo estoy usando: '@ request.cookie_jar.signed [: foo] = 'bar'' –

18

Me encontré con esta pregunta mientras buscaba en Google una solución a un problema similar, así que lo publicaré aquí. Esperaba establecer una cookie firmada en Rspec antes de probar una acción del controlador. Los siguientes trabajó:

jar = ActionDispatch::Cookies::CookieJar.build(@request) 
jar.signed[:some_key] = "some value" 
@request.cookies['some_key'] = jar[:some_key] 
get :show ... 

cuenta que la siguiente no funcionó:

# didn't work; the controller didn't see the signed cookie 
@request.cookie_jar.signed[:some_key] = "some value" 
get :show ... 
+0

Simplemente encontré esto y resolvió mi problema a la perfección, pero como una adición importante, tuve que cambiar: @request. cookies [: alguna_clave] a: @ request.cookies ["some_key"] – Atiaxi

+0

Great balexand. Te deseo que pueda darte 10 pulgares arriba. – allesklar

+0

@Atiaxi, usando Rails 3.2.12 y podría usar el símbolo para acceder a @ request.cookies [: some_key] = jar [: some_key] –

0

El problema también parece haber pruebas.

Aquí hay algunos códigos y pruebas que utilicé para TDD, la situación en la que desea establecer el valor de una cookie para pasar un valor de parámetro a una vista.

Prueba funcional:

test "reference get set in cookie when visiting the site" do 
    get :index, {:reference => "121212"} 
    refute_nil cookies["reference"] 
end 

SomeController:

before_filter :get_reference_code 

ApplicationController:

def get_reference_code 
    cookies.signed[:reference] ||= params[:reference] 
end 

en cuenta que la línea refute_nil, las cookies es una cadena ... que es una cosa que también hizo que esta prueba no pasara, ponía un símbolo en cookies[:reference], la prueba no así, así que no hice eso.

7

Después de mirar el código de Rails que se encarga de esta creé un ayudante de prueba para esto:

def cookies_signed(name, opts={}) 
    verifier = ActiveSupport::MessageVerifier.new(request.env["action_dispatch.secret_token".freeze]) 
    if opts[:value] 
     @request.cookies[name] = verifier.generate(opts[:value]) 
    else 
     verifier.verify(cookies[name]) 
    end 
    end 

añadir esto a test_help.rb, entonces se puede establecer una cookie firmado con:

cookies_signed(:foo, :value => 'bar') 

y leerlo con:

cookies_signed(:foo) 

Un poco hacker tal vez, pero hace el trabajo para mí.

+0

Bien hecho, he cambiado el nombre del método a #signed_cookie, y abofeteado en un módulo para mezclar en las especificaciones del controlador. [Ver esta esencia] (https://gist.github.com/2694930) para una referencia –