How to test ETAG caching?

Is it possible to cover my controller, which depresses heavily on Etags with unit tests?

Here is what I am trying to do: in case the page is not outdated (which means it is new), I am adding some heading for the response.

When I try to check everything (rspec), no matter how many similar queries I have, I still get 200 OK instead of 304, and my title does not change. Also, if I track request.fresh? (Response), he is ALWAYS a lie.

However, it works fine in the browser. I already tried to specify ActionController :: Base.perform_caching = true, this does not change the general situation.

thanks

+6
ruby-on-rails rspec etag
source share
5 answers

Ok, here's the point:

Before deleting a request, read everything related to ETags in Rails code and do not forget to install:

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

Because they are necessary for testing ETag.

+4
source share

Here's how you can check if the second request returns a 304 response:

  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 
+7
source share

Rails hashes: etag, which you provide:

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

so install something simple like

 frash_when(:etag => 'foo') 

will only be called with the correct digest (double quotes are needed)

 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 

same for modified:

 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 
+4
source share

This method is very useful for testing rspec -

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

+1
source share

Rails 4.2 now also takes into account the template digest. For me it worked:

 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' ) 
0
source share

All Articles