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

Était-ce utile?

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 -

https://gist.github.com/brettfishman/3868277

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top