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.