Skip to content
jacklin edited this page Aug 29, 2014 · 1 revision

Testing

Testing your policies isn't very difficult and it will vary a bit from app to app so I'll just show what I do as an example.

The app I use canner for is using minitest-rails so the examples will be using that instead of rspec.

require 'test_helper'
include AuthMacros

class UserPolicyTest < ActiveSupport::TestCase

  describe UserPolicy do
    let(:current_user) {users(:joe)}
    let(:current_branch) { branches(:pittsburgh) }

    describe 'canner_scope' do

      it 'should return an empty user unless when not index method' do
        policy = UserPolicy.new(current_user, 'show', current_branch)
        assert_equal policy.canner_scope, User.none
      end

      it 'should return only users for the correct company' do
        policy = UserPolicy.new(current_user, 'index', current_branch)
        users = policy.canner_scope

        assert_equal users.size, 1

        policy = UserPolicy.new(current_user, 'index', monaca)
        users = policy.canner_scope

        assert_equal users.size, 0
      end

    end

    describe 'can?' do

      it 'should verify sysop access' do
        allowed_methods = [:new, :index, :create, :update, :edit, :lookup_user, :selected_user]

        policy_test(current_user, 'sysop', allowed_methods, 'user')
      end

    end

  end

end

I wrote a method policy_test in a module that I mix in. This makes it pretty easy to test all my policies quickly.

I just want to make sure the policy allows access to only the actions I expect and denies access to those I don't expect.

Here's what AuthMacro looks like:

module AuthMacros

  def policy_test(user, rolename, allowed_actions, model_name, branch=user.active_branch)
    all_actions = find_all_actions(model_name)

    # Yours might be something like: user.role = rolename
    user.grant!(rolename, branch)

    allowed_actions.each do |method|
      assert policy_can?(model_name, user, branch, method), "Not permitted to :#{method}, but test thinks it is"
    end

    (all_actions - allowed_actions).each do |method|
      assert_not policy_can?(model_name, user, branch, method), "Permitted to :#{method}, but test doesn't expect it"
    end

  end

  def policy_can?(model_name, user, branch, method)
    "#{model_name.classify}Policy".constantize.send(:new, user, branch, method).can?
  end

  def find_all_actions(model_name)
    "#{model_name.classify.pluralize(2)}Controller".constantize.send(:action_methods).map{|m| m.to_sym}
  end

end
Clone this wiki locally