ActsAsRolePermittable 拡張(3)

テストクラスを書きます。使用例とテーブル設計から察するに、model.role_permissions("index") は WjRolePermissionKey クラスのオブジェクトになるはずですですから、roles=(val), permit?(user)のテストケースが必要でしょう。(anonymous=はActiveRecordにより自動追加されるのでいいでしょう。
一方で、mode. クラスは acts_as_role_permisstableを適用するクラスになります。したがって、こちらには追加されるべきメソッド(role_permissions(key=nil), permit?(user)テストクラスを提供します。

# test/units/acts_as_role_permittable_test.rb
require File.dirname(__FILE__) + '/../test_helper'
class ActsAsRolePermittaleTest < Test::Unit::TestCase
  fixtures :wj_components, :wj_component_pages, :wj_users, :wj_roles, :wj_roles_users

  alias :component_pages :wj_component_pages
  alias :users :wj_users

  def setup
    @secure_page    = component_pages(:secure_page)
    @administrators = users(:ma)             # belongs to administrators
    @users          = users(:elly)           # belongs to users
    @others         = users(:user5)          # belongs to others
    @nobelongs      = users(:user6)          # belongs to no roles
  end

  def test_permit_anonymous_property
    @secure_page.permit_anonymous = true
    assert_true  @secure_page.permit_anonymous?
    @secure_page.permit_anonymous = false
    assert_false @secure_page.permit_anonymous?
  end

  def test_permit_roles_property_by_objects
    @secure_page.permit_roles = WjRole.find(:all)
    assert_equal WjRole.find(:all), @secure_page.permit_roles
  end

  def test_permit_roles_property_by_symbols
    @secure_page.permit_roles = WjRole.find(:all).map(&:name)
    assert_equal WjRole.find(:all), @secure_page.permit_roles
  end

  def test_permit_roles_property_by_ids
    @secure_page.permit_roles = WjRole.find(:all).map(&:id)
    assert_equal WjRole.find(:all), @secure_page.permit_roles
  end

  def test_permit_administrators
    @secure_page.permit_anonymous = false
    @secure_page.permit_roles = [:administrators]
    assert_permission([@administrators],
                      [@users, @others, @nobelongs])
  end

  def test_permit_one_of_users
    @secure_page.permit_anonymous = false
    @secure_page.permit_roles = [:users]
    assert_permission([@administrators, @users],
                      [@others, @nobelongs])
  end

  def test_permit_both_users
    @secure_page.permit_anonymous = false
    @secure_page.permit_roles = [:users, :others]
    assert_permission([@administrators, @users, @others],
                      [@nobelongs])
  end

  def test_permit_anonymous
    @secure_page.permit_anonymous = true
    @secure_page.permit_roles = []
    assert_permission([@administrators, @users, @others, @nobelongs],
                      [])

  end

  # helper method for checking permission
  def assert_permission(permitted, not_permitted, key = nil)
    if key
      permitted.each     { |user| assert_true  @secure_page.permit?(user, key) }
      not_permitted.each { |user| assert_false @secure_page.permit?(user, key) }
    else
      permitted.each     { |user| assert_true  @secure_page.permit?(user) }
      not_permitted.each { |user| assert_false @secure_page.permit?(user) }
    end
  end
end
require File.dirname(__FILE__) + '/../test_helper'

class WjRolePermissionKeyTest < Test::Unit::TestCase
  fixtures :wj_role_permission_keys, :wj_users, :wj_roles, :wj_roles_users

  alias :users :wj_users

  def setup
    @administrators = users(:ma)             # belongs to administrators
    @users          = users(:elly)           # belongs to users
    @others         = users(:user5)          # belongs to others
    @nobelongs      = users(:user6)          # belongs to no roles

    @permission_key = WjRolePermissionKeys(:all, :conditions => ["permission_key = 'index' AND wj_role_permittable_id = 1"])
  end

  def test_permit_roles_with_symbols
    @permission_key.permit_roles = WjRole.find(:all).map(:name).map(&:to_sym)
    assert_equal WjRole.find(:all), permission_key.wj_roles
  end

  def test_permit_roles_with_strings
    @permission_key.permit_roles = WjRole.find(:all).map(&:name)
    assert_equal WjRole.find(:all), permission_key.wj_roles
  end

  def test_permit_roles_with_ids
    @permission_key.permit_roles = WjRole.find(:all).map(&:id)
    assert_equal WjRole.find(:all), permission_key.wj_roles
  end

  def test_permit_roles_with_object
    @permission_key.permit_roles = WjRole.find(:all).map(&:id)
    assert_equal WjRole.find(:all), permission_key.wj_roles
  end

  def test_permit?
    @permission_key.permit_roles = [:administrators]
  end

  def assert_permission(allows, denies)
    allows.each { |user| assert_true  @permission_key.permit?(user) }
    denies.each { |user| assert_false @permission_key.permit?(user) }
  end
end

ほとんど同じコードなのですが、テストなので省略しません。というかテストで冗長なコードがでてくるときは、実装で省略できるチャンスだと思うようにしています。
つまり、component_page.permit? とかは、component_page.wj_role_permission_keys.permit? に委譲して実現しよう、というアプローチです*1

*1:ただし、これにより、has_many, hbtm関連で、関連先のオブジェクトが未ロードの場合は、余計なSQL文が発生するので、ボトルネックになるかもしれない、と覚悟します。まぁ、あとでやるメソッドで