Created
October 10, 2012 20:39
-
-
Save brettfishman/3868277 to your computer and use it in GitHub Desktop.
Testing HTTP caching using RSpec and CanCan
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Given a controller that looks like this | |
class ModelsController < ApplicationController | |
load_and_authorize_resource #CanCan | |
def show | |
if stale? @model | |
respond_to do |format| | |
format.json do | |
@model | |
end | |
end | |
end | |
end | |
end | |
# The spec looks like this | |
context "http caching" do | |
context "given a model" do | |
before do | |
@model = Factory :model, :user => @brett | |
end | |
context "on the first request" do | |
it "returns a 200" do | |
get :show, :id => @model.id, :format => :json | |
response.code.should == "200" | |
end | |
end | |
context "on a subsequent request" do | |
before do | |
get :show, :id => @model.id, :format => :json | |
response.code.should == "200" | |
response.headers['ETag'].should be_present | |
response.headers['Last-Modified'].should be_present | |
@etag = response.headers['ETag'] | |
@last_modified = response.headers['Last-Modified'] | |
end | |
context "if it is not stale" do | |
before do | |
request.env['HTTP_IF_NONE_MATCH'] = @etag | |
request.env['HTTP_IF_MODIFIED_SINCE'] = @last_modified | |
end | |
it "returns a 304" do | |
get :show, :id => @model.id, :format => :json | |
response.code.should == "304" | |
end | |
end | |
context "if it has been updated" do | |
before do | |
sleep 1 # To ensure the model.updated_at has a delta of at least 1 sec | |
@model.touch | |
request.env['HTTP_IF_NONE_MATCH'] = @etag | |
request.env['HTTP_IF_MODIFIED_SINCE'] = @last_modified | |
end | |
it "returns a 200" do | |
# Initialize account_item instance in the controller so CanCan | |
# will load up the resource from the db again | |
controller.instance_variable_set(:@model, nil) | |
get :show, :id => @model.id, :format => :json | |
response.code.should == "200" | |
end | |
end | |
end | |
end | |
end |
Is there a reason that the expectation on the first request are in the before
block instead of in the "on the first request" context?
context "on the first request" do
it "returns a 200" do
get :show, :id => @model.id, :format => :json
response.code.should == "200"
end
it "set an ETag header" do
response.headers['ETag'].should be_present
end
it "sets 'Last-Modified'" do
response.headers['Last-Modified'].should be_present
end
end
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Line 58 is necessary because CanCan "caches" the resource instance internally (see #load_resource in lib/cancan/controller_resource.rb) if it has already been loaded. This is an issue when testing a controller instance, as the next time a request is made to the same instance, the resource will be set to the cached one, which we don't want.