2011-06-27 12 views
13

Hay mucha confusión sobre la configuración de las cookies en rspec http://relishapp.com/rspec/rspec-rails/v/2-6/dir/controller-specs/file/cookies¿Cómo se prueba caducidad de cookies en los carriles rspec

en su controlador, normalmente se puede escribir

cookies['transaction_code'] = { :expires => 300.seconds.from_now, :value => c } 

pero en rspec sólo puedo escribir

request.cookies['transaction_code'] = transaction_code 

si digo

request.cookies['transaction_code'] = { :expires => 300.seconds.from_now, :value => c } 

i obtener el hash atrás como valor de galletas [ 'transaction_code'] en mi controlador.

Ahora mi pregunta es: ¿Cómo puedo configurar/prueba de caducidad de cookies a continuación, en un ejemplo de prueba del controlador rspec?

ACTUALIZACIÓN: En cuestión de segundos: Lo que quiero decir es: ¿cómo pruebo si el controlador reacciona a una cookie caducada como se esperaba, pero de hecho una cookie caducada es como ninguna cookie si confío en la implementación de cookies, que debería hacer, así que después de todo, tal vez mi pregunta no tenga sentido. Si este es el caso, tengo que probar si (otra) Acción controlador establece una cookie de expirar correctamente, pero ¿cómo lo hago si las cookies [ 'transaction_code'] en la prueba sólo da el valor de nuevo?

Respuesta

17

Navegadores do not send cookie attributes back to the server. Esta es la razón por la que solo puede enviar el par clave-valor a la acción.

Dado que puede suponer que Rails, Rack y navegadores hacen lo correcto con los argumentos, todo lo que necesita probar son los argumentos que su código está pasando al CookieJar.

Para probar que la supresión se está estableciendo adecuadamente en el establecimiento de la cookie controlador, se puede apagar el método #cookies y asegúrese de que la configuración correcta se están pasando a ella.

# app/controllers/widget_controller.rb 
... 
def index 
    cookies[:expiring_cookie] = { :value => 'All that we see or seem...', 
            :expires => 1.hour.from_now } 
end 
... 

# spec/controllers/widget_controller_spec.rb 
... 
it "sets the cookie" do 
    get :index 
    response.cookies['expiring_cookie'].should eq('All that we see or seem...') 
               # is but a dream within a dream. 
               #    - Edgar Allan Poe 
end 

it "sets the cookie expiration" do 
    stub_cookie_jar = HashWithIndifferentAccess.new 
    controller.stub(:cookies) { stub_cookie_jar } 

    get :index 
    expiring_cookie = stub_cookie_jar['expiring_cookie'] 
    expiring_cookie[:expires].to_i.should be_within(1).of(1.hour.from_now.to_i) 
end 
... 

Probando mucho más que esto es hervir el océano. En algún momento, debe suponer que la pila en la que está sentado (por ejemplo, Rails, Rack, el servidor web, TCP/IP, SO, navegadores web, etc.) funciona correctamente y se centra en el código que controla.

+0

nice one kro, acepto su respuesta, no estoy seguro de anotar cookiestore, por mencionar lo obvio El acceso a la cookie jar es indiferente al uso de símbolos o cadenas como claves a diferencia de su hash stub. En general, me siento incómodo tropezando con lo que es parte del marco. Además, ¿es algo así como expiring_cookie [: expires] .to_i.hould_within (1) .of (1.hour.from_now.to_i) la mejor práctica para probar la configuración de tiempo dinámico? –

+0

No, probablemente haría algo diferente con el matcher para el 'DateTime' en la especificación real. Mi objetivo era proporcionar algo que pasaría como ilustración, ya que '==' no. – krohrbaugh

+0

En cuanto a su problema de acceso indiferente; esto se soluciona fácilmente mediante el uso de 'ActiveSupport :: HashWithIndifferentAccess' en lugar de stdlib' Hash'. Actualicé el código de ejemplo para reflejar esto. – krohrbaugh

0

Otra opción usando Timecop:

Timecop.freeze(Time.now) 

expect(controller.send(:cookies)).to receive(:[]=).with('cookie_name', 
    value: 'whatever', 
    expires: 1.hour.from_now 
) 

get :index 
0

Vine de un futuro con esto:

it 'sets the cookie expiration' do 
    stub_cookie_jar = HashWithIndifferentAccess.new 
    allow(controller).to receive(:cookies).and_return(stub_cookie_jar) 
    get :index 
    expiracy_date = stub_cookie_jar[:expires] 
    expect(expiracy_date).to be_between(1.hour.from_now - 1.minutes, 
             1.hour.from_now) 
    end 
Cuestiones relacionadas