Comment rails test de mise en cache ETag?
-
27-09-2019 - |
Question
Est-il possible de couvrir mon contrôleur, qui est depeinding fortement Etags avec les tests unitaires?
Voici ce que je suis en train de le faire: dans le cas si la page n'est pas périmé (ce qui signifie qu'il est frais), j'ajoute une en-tête de la réponse.
Quand je suis en train de tester tout (rspec), peu importe combien de demandes similaires j'ai, je reçois encore 200 OK au lieu de 304, et ma tête ne soit pas modifié. De plus, si je voie request.fresh? (Réponse), il est toujours faux.
Cependant, cela fonctionne parfaitement dans le navigateur. Je l'ai déjà essayé de ActionController d'Etat :: Base.perform_caching = true, cela ne change pas la situation globale.
Merci
La solution 3
Ok, voici un point:
Avant de frapper la demande, lire tout ce qui est lié à ETags dans le code Rails et ne pas oublier de définir:
request.env["HTTP_IF_MODIFIED_SINCE"]
request.env["HTTP_IF_NONE_MATCH"]
Comme ils sont nécessaires pour les tests ETag.
Autres conseils
Voici comment vous pouvez tester si la deuxième demande retourne 304 réponse:
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 hashs le: ETAG vous fournissez:
headers['ETag'] = %("#{Digest::MD5.hexdigest(ActiveSupport::Cache.expand_cache_key(etag))}")
réglage simple comme quelque chose
frash_when(:etag => 'foo')
ne sera déclenchée par la digestion droite (les guillemets sont nécessaires)
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
même pour modifier:
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
Ce point essentiel est très utile test re etag dans rspec -
Rails 4.2 maintenant prend également en compte pour le condensé du modèle. Pour moi, ce qui suit travaillé:
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'
)
Au moins dans Rails 5.2, la solution de szeryf échoue. Cette variation fonctionne:
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
Voir Rails guides: https: //guides.rubyonrails .org / testing.html # mise en-têtes et-cgi-variables