When testing Controller actions for access restriction, I was building a set of tests for each controller that were in a similar format to this:
describe "access control" do it "should prevent access by non-logged-in users" it "should prevent access by normal users" it "should prevent access by editor users" it "should prevent access by admin users" it "should allow access by super admin users" end
Unforunately, this was neither dry, complete, nor very readable, so I have come up with the following helper that allows you to specify the access restrictions for a number of methods:
In your spec_helper.rb file, add the following function:
def access_control (code, options={})
options = {:allow => [], :disallow => []}.merge(options)
options[:allow].each do |user|
it "#{code} should allow #{user.to_s}" do
login_as(user)
eval code
response.should_not redirect_to(login_path)
end
end
options[:disallow].each do |user|
it "#{code} should disallow #{user.to_s}" do
login_as(user)
eval code
response.should redirect_to(login_path)
end
end
end
Then in the specs for your controller, call the function as follows:
access_control("get :index", {:allow => [:super_admin], :disallow => [:quentin, :admin]})
This allows you to very quickly build a set of specs that fully describe how access control to your methods should restrict your users:
[ "get :show, :id => 0",
"get :new",
"post :create, :setting_value => {:value => 'A new setting', :group => 0}",
"get :edit",
"put :update, :id => SettingValue.first.id, :setting_value => {:value => 'changed'}",
"delete :destroy, :id => SettingValue.first.id"
].each do |action|
access_control(action, {:allow => [:super_admin], :disallow => [:quentin, :admin]})