2010-04-15 32 views
6

Czy mogę kontrolować mój kontroler, który jest wysoce nieskuteczny w testach Etags?Jak testować pamięć podręczną ETag?

Oto, co próbuję zrobić: w przypadku, gdy strona nie jest nieaktualna (co oznacza, że ​​jest świeża), dodaję nagłówek do odpowiedzi.

Kiedy próbuję przetestować to wszystko (rspec), bez względu na to, ile mam podobnych żądań, wciąż otrzymuję 200 OK zamiast 304, a mój nagłówek nie jest modyfikowany. Ponadto, jeśli śledzę request.fresh? (Odpowiedź), ZAWSZE jest to fałsz.

Jednak doskonale działa w przeglądarce. Próbowałem już określić ActionController :: Base.perform_caching = true, nie zmienia to ogólnej sytuacji.

Dziękuję

Odpowiedz

4

Ok, oto punkt:

przed pójściem na żądanie, przeczytać wszystko, co jest związane z Etags w kodzie Rails i nie zapomnij ustawić:

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

Ponieważ są one wymagane do testowania ETag.

+0

Witam, czy możesz wyjaśnić szczegółowo, co to oznacza? Kiedy ustawię request.env nadal nie zawiera etag. – Tosa

+0

@Tosa, zobacz poniżej moją odpowiedź na niektóre pomysły (nie mogłem opublikować tak dużo kodu w komentarzu). – szeryf

+0

Jak to jest odpowiedź, nie mówiąc już o zaakceptowanej odpowiedzi? Mówisz, że wykonujesz badania i ustawiasz kilka zmiennych env, ale nie mówisz, co badać i na co ustawić zmienne env. –

4

Szyny skróty: etag podać:

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

więc ustawienie coś prostego jak

frash_when(:etag => 'foo') 

byłyby uruchamiane tylko przez prawe trawienia (podwójne cudzysłowy są konieczne)

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 

samo dla modyfikacji:

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, to było pytanie sprzed wieków. Myślę, że nadal było to szynami 2.3.5, więc od tego czasu wiele się zmieniło. – 0100110010101

7

Oto w jaki sposób można sprawdzić, czy drugi wniosek zwraca 304 odpowiedzi:

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 teraz także bierze w aby uwzględnić wyciąg z szablonu. Dla mnie zadziałało następujące:

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' 
) 
Powiązane problemy