2010-04-15 16 views
6

¿Es posible cubrir mi controlador, que es altamente confiable en Etags con pruebas unitarias?Cómo probar los raíles ETag caching?

Esto es lo que estoy tratando de hacer: en caso de que si la página no es obsoleta (lo que significa que es reciente), estoy agregando algunos encabezado a la respuesta.

Cuando estoy tratando de probarlo todo (rspec), no importa cuántas solicitudes similares tengo, todavía recibo 200 en lugar de 304, y mi encabezado no se modifica. Además, si rastreo request.fresh? (Response), SIEMPRE es falso.

Sin embargo, funciona perfectamente en el navegador. Ya he intentado indicar ActionController :: Base.perform_caching = true, no cambia la situación general.

Gracias

Respuesta

4

Ok, esto es un punto:

Antes de golpear la solicitud, leer todo lo que está relacionado con ETags en el código de Rails y no se olvide de establecer:

request.env["HTTP_IF_MODIFIED_SINCE"] 
request.env["HTTP_IF_NONE_MATCH"] 

Dado que son necesarios para las pruebas ETag.

+0

Hola, ¿podría explicar en detalle qué significa eso? Cuando configuro request.env, todavía no contiene el etag. – Tosa

+0

@Tosa, consulte mi respuesta a continuación para obtener algunas ideas (no pude publicar tanto código en un comentario). – szeryf

+0

¿Cómo es esta una respuesta, y mucho menos la respuesta aceptada? Usted dice investigar y establecer algunas variables env, pero no dice qué investigar y a qué establecer las variables env. –

4

rieles Marca el: etag usted proporciona:

headers['ETag'] = %("#{Digest::MD5.hexdigest(ActiveSupport::Cache.expand_cache_key(etag))}") 

por lo que establecer algo simple como

frash_when(:etag => 'foo') 

sólo sería provocada por el digesto derecha (las comillas son necesarias)

def with_etag 
    if stale?(:etag => 'foo') 
    render :text => 'OK' 
    end 
end 

... tested by ... 

@request.env['HTTP_IF_NONE_MATCH'] = '"acbd18db4cc2f85cedef654fccc4a4d8"' 
get :with_etag 
assert_equal 304, @response.status.to_i 

mismo para modificado:

def with_modified 
    if stale?(:last_modified => 1.minute.ago) 
    render :text => 'OK' 
    end 
end 

... tested by ... 

@request.env['HTTP_IF_MODIFIED_SINCE'] = 2.minutes.ago.rfc2822 
get :with_modified 
assert_equal 304, @response.status.to_i 
+0

oh, esa era una pregunta de hace años. Creo que todavía han sido los rieles 2.3.5, por lo que las cosas pueden haber cambiado mucho desde entonces. – 0100110010101

7

Así es como se puede comprobar si la segunda solicitud devuelve 304 respuesta:

get action, params 
    assert_response 200, @response.body 
    etag = @response.headers["ETag"] 
    @request.env["HTTP_IF_NONE_MATCH"] = etag 
    get action, params 
    assert_response 304, @response.body 
0

Rails 4.2 ahora también se toma en para dar cuenta del resumen de la plantilla. Para mí, lo siguiente funcionó:

def calculate_etag(record, template) 
    Digest::MD5.hexdigest(ActiveSupport::Cache.expand_cache_key([ 
    record, 
    controller.send(:lookup_and_digest_template, template) 
    ])).inspect 
end 

def set_cache_headers(modified_since: nil, record: nil, template: nil) 
    request.if_modified_since = modified_since.rfc2822 
    request.if_none_match = calculate_etag(record, template) 
end 

set_cache_headers(
    modified_since: 2.days.ago, 
    record: @book, 
    template: 'books/index' 
)