Skip to content

Instantly share code, notes, and snippets.

@realmyst
Created February 1, 2012 13:29
Show Gist options
  • Save realmyst/1716952 to your computer and use it in GitHub Desktop.
Save realmyst/1716952 to your computer and use it in GitHub Desktop.
Helper for testing ACL
module AuthorizationTestHelper
#helper module
module AuthenticatedTestHelper
include AuthHelper
def login_as(role_or_user = :admin, role_sym = :admin)
if role_or_user.kind_of? model_user
user = role_or_user
else
user = factory_user
role_sym = role_or_user
end
role = find_role_by_name(role_sym.to_s)
raise "Role '#{role_sym}' does not exist" unless role
user.roles = [role]
sign_in(user)
user
end
# application depending
def all_roles_keys
Role.all.map(&:short_name)
end
def find_role_by_name(role_name)
Role.find_by_short_name(role_name)
end
def factory_user(params = nil)
Factory :user, params
end
def model_user
User
end
end
include AuthenticatedTestHelper
#result builder
class ActionBuilder
def self.build(&block)
builder = new &block
builder.result
end
def initialize(&block)
@roles = {:allow => [], :deny => []}
instance_eval &block
end
def role(role = :admin, type = :allow, &block)
block = @default_params unless block
@roles[type] << {:name => role, :params => block}
end
def allow(*args, &block)
args.each do |r|
role(r, :allow, &block)
end
end
def deny(*args, &block)
args.each do |r|
role(r, :deny, &block)
end
end
def result
complete_denied_roles
@roles
end
def complete_denied_roles
allowed_roles = @roles[:allow].map do |role|
role[:name].to_s
end
denied_roles = all_roles_keys - allowed_roles
@roles[:deny] = denied_roles.map do |role|
{:name => role, :params => @default_params}
end
end
def params(&block)
@default_params = block
end
end
# main methods
def auth_for(&block)
block.call
end
def get(*actions, &block)
called_method :get, actions, &block
end
def post(*actions, &block)
called_method :post, actions, &block
end
def put(*actions, &block)
called_method :put, actions, &block
end
def delete(*actions, &block)
called_method :delete, actions, &block
end
def called_method(method, actions, &block)
result = ActionBuilder.build(&block)
generate_tests(actions, result, method)
end
def generate_tests(actions, result, method)
actions = Array(actions)
actions.each do |action|
result[:allow].each do |role|
allow_test(method, action, role[:name], role[:params])
end
result[:deny].each do |role|
deny_test(method, action, role[:name], role[:params])
end
end
end
def allow_test(method, action, role, params = nil)
test "allow to #{method} #{action} for #{role}" do
user = login_as role
attrs = before if respond_to? :before
attrs = instance_exec(user, attrs, &params) if params
assert_nothing_raised YaAcl::AccessDeniedError do
send(method, action, attrs)
end
end
end
def deny_test(method, action, role, params = nil)
test "deny to #{method} #{action} for #{role}" do
user = login_as role
attrs = before if respond_to? :before
attrs = instance_exec(user, attrs, &params) if params
assert_raise YaAcl::AccessDeniedError do
send(method, action, attrs)
end
end
end
end
class Web::Admin::WelcomeControllerTest < ActionController::TestCase
auth_for do
get :index do
allow :admin, :moderator
#by default, denied for all other, but you can use method #deny
deny :guest
end
end
end
class Web::Admin::PagesControllerTest < ActionController::TestCase
def before
@page = Factory :page
@params = {:id => @page.id}
end
auth_for do
get :index, :new do
allow :admin, :moderator
end
put :update do
allow :admin do
#this block will replace before-block
@params
end
end
put :update do
allow :moderator do |user, params|
params[:page][:user_id] = user.id
params
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment