Monthly Archives: November 2011

Rspec Shared Example for denying access to CRUD

I’m currently working on an app that has 4 user contexts: not logged in, logged in as subscriber, logged in as campaign manager and logged in as administrator. I guess you can imagine the horror for writing tests for them. As you’d probably guess, I only want to allow access of some controllers to a particular user context and barring everything else.

Spent an hour or two making the following shared context work:

shared_examples "denied on all resource methods" do |class_name, attributes|
  before(:each) do
    @subject = class_name.capitalize.constantize.create! attributes
  end
 
  actions = {
    :index => :get,
    :show => :get,
    :new => :get,
    :create => :post,
    :update => :put,
    :destroy => :delete
  }
 
  actions.each_pair do |action, verb|
    specify "I should be denied access to ##{action}" do
      send(verb, action, :id => @subject.id.to_s, class_name.to_sym => @subject)
      response.should_not be_success
    end
 
    specify "I should be redirected" do
      send(verb, action, :id => @subject.id.to_s, class_name.to_sym => @subject)
      response.should be_redirect
    end
  end
end

I call it like so (I’m using factory_girl):

  context "when logged in as campaign manager" do
    it_should_behave_like "denied on all resource methods", "category", Factory.attributes_for(:category)
  end

Thanks to David Chelimsky on this SO question. I used his answer as a baseline. :)