Wie man Testschienen ETag-Caching?
-
27-09-2019 - |
Frage
Ist es möglich, meinen Controller zu decken, die hoch ist depeinding auf Etags mit Unit-Tests?
Hier ist, was ich versuche zu tun: wenn Seite in Fall nicht abgestanden (was bedeutet, dass es frisch ist), ich bin das Hinzufügen einiger Header Antwort.
Wenn ich versuche, das alles (rspec) zu testen, egal wie viele ähnliche Anfragen ich habe, ich erhalten noch 200 OK statt 304 und meine Header geändert bekommen nicht. Außerdem, wenn ich request.fresh verfolgen? (Antwort), es ist immer falsch.
Doch es funktioniert perfekt in Browser. Ich habe bereits versucht, in dem Zustand Action :: Base.perform_caching = true, es nicht die Gesamtsituation ändern.
Danke
Lösung 3
Ok, hier ist ein Punkt:
Bevor die Anforderung schlägt, lesen Sie alles, dass die zu ETags in Rails-Code im Zusammenhang und nicht vergessen Satz:
request.env["HTTP_IF_MODIFIED_SINCE"]
request.env["HTTP_IF_NONE_MATCH"]
Da sie für ETag Tests erforderlich sind.
Andere Tipps
Hier ist, wie Sie können testen, ob zweite Anforderung kehrt 304 Antwort:
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
Rails-Hashes der: etag Sie bieten:
headers['ETag'] = %("#{Digest::MD5.hexdigest(ActiveSupport::Cache.expand_cache_key(etag))}")
so einstellen etwas Einfaches wie
frash_when(:etag => 'foo')
würde nur durch die rechte verdauen (die doppelten Anführungszeichen sind erforderlich)
ausgelöst werdendef 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
gleiche gilt für geändert:
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
Dieser Kern ist sehr nützlich Wieder etag Tests in rspec -
Rails 4.2 jetzt nimmt auch um die von der Vorlage verdauen zu berücksichtigen. Für mich ist die folgende gearbeitet:
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'
)
Mindestens in Rails 5.2, szeryf Lösung ausfällt. Diese Variante funktioniert:
get action, parms
assert_response 200, @response.code
etag = @response.headers["ETag"]
get action, parms, headers: { "HTTP_IF_NONE_MATCH": etag }
assert_response 304, @response.code
Siehe Rails Guides: https: //guides.rubyonrails .org / testing.html # Einstellung-Header-und-cgi-Variablen