require 'test_helper' class ActiveSupport::TestCase def self.should_handle_basic_role_manipulation(subject_class) context "for #{subject_class.to_s}: " do setup do Role.delete_all [subject_class, Foo, Bar, Uuid].each { |c| c.delete_all } @subject1 = subject_class.create! @subject2 = subject_class.create! @foo = Foo.create! @bar = Bar.create! @uuid = Uuid.create!(:uuid => "C41642EE-2780-0001-189F-17F3101B26E0") end should "not have any roles by default" do %w(user manager admin owner).each do |role| assert_false @subject1.has_role?(role) assert_false @subject1.has_role?(role, @foo) end end context "Given a global role" do setup do @subject1.has_role!(:admin) end should_change "create a role successfully", :by => 1 do Role.count end should "not distinguish between symbols and strings" do assert @subject1.has_role?("admin") end should "assign roles to a specific user" do assert @subject1.has_role?(:admin) assert_false @subject2.has_role?(:admin) end should "distinguish between names of roles" do assert_false @subject1.has_role?(:manager) end should "not count a global role as an object role" do assert_false @subject1.has_role?(:admin, @foo) assert_false @subject1.has_roles_for?(@foo) end should "not let objects accept it" do [@foo,@bar].each do |obj| assert_false obj.accepts_role?(:admin, @subject1) end end should "reading roles should not add another role" do assert_no_difference "Role.count" do @subject1.has_role!(:admin) end end context "with two users" do setup do @subject2.has_role!(:admin) end should "remove assignments to roles through has_no_role!" do @subject1.has_no_role!(:admin) assert_false @subject1.has_role?(:admin) end should "only delete roles when they have no assignments" do assert_no_difference 'Role.count' do @subject1.has_no_role!(:admin) end assert_difference 'Role.count', -1 do @subject2.has_no_role!(:admin) end assert_false @subject1.has_role?(:admin) assert_false @subject2.has_role?(:admin) end end end context "Given an object role" do setup do @subject1.has_role!(:admin, @foo) end should_change "create a role successfully", :by => 1 do Role.count end should "assign roles to a specific user" do assert @subject1.has_role?(:admin, @foo) assert @subject1.has_roles_for?(@foo) assert @subject1.has_role_for?(@foo) roles = @subject1.roles_for(@foo) assert_equal 1, roles.length assert_equal "admin", roles.first.name assert_false @subject1.has_role?(:manager, @foo) assert_false @subject2.has_role?(:admin, @foo) assert_false @subject2.has_roles_for?(@foo) end should "let the object accept it" do assert @foo.accepts_role?(:admin, @subject1) assert_false @bar.accepts_role?(:admin, @subject1) @bar.accepts_role!(:admin, @subject1) assert @bar.accepts_role?(:admin, @subject1) @bar.accepts_no_role!(:admin, @subject1) assert_false @bar.accepts_role?(:admin, @subject1) end should "allow the object to list its roles" do assert_equal 1, @foo.roles.size end should "not count an object role as an global role" do assert_false @subject1.has_role?(:admin) end should "reuse roles" do assert_no_difference 'Role.count' do @subject2.has_role!(:admin, @foo) end assert_difference 'Role.count', 1 do @subject2.has_role!(:manager, @foo) end end context "with two users" do setup do @subject1.has_role!(:admin) @subject2.has_role!(:admin, @foo) @subject1.has_role!(:admin, @bar) end should "let objects be able to query their subjects" do assert_same_elements @foo.list_subjects_for(:admin), [@subject1, @subject2] assert_same_elements @foo.list_subjects_all_roles, [@subject1, @subject2] end should "dynamically build methods to query" do assert_same_elements @foo.list_subjects_for(:admin), @foo.list_admins end should "remove assignments to object roles through has_no_role!" do @subject1.has_no_role!(:admin, @foo) assert @subject1.has_role?(:admin) assert @subject1.has_role?(:admin, @bar) assert_false @subject1.has_role?(:admin, @foo) end should "only delete roles when they have no assignments" do assert_difference 'Role.count', 0 do @subject2.has_no_role!(:admin, @foo) end assert_false @subject2.has_role?(:admin) assert_difference 'Role.count', -1 do @subject1.has_no_role!(:admin, @foo) end assert_false @subject1.has_role?(:admin, @foo) end should "delete all roles for a given object with has_no_roles_for!" do assert_difference 'Role.count', 1 do @subject1.has_role!(:manager, @bar) end assert_difference '@subject1.assigned_roles.size', -2 do @subject1.has_no_roles_for!(@bar) end assert_false @subject1.has_roles_for?(@bar) assert @subject1.has_role?(:admin) assert @subject1.has_role?(:admin, @foo) end should "delete all roles with has_no_roles!" do @subject1.has_no_roles! assert_equal @subject1.assigned_roles.length, 0 end end end end end end class RolesTest < ActiveSupport::TestCase context "role testing" do should_handle_basic_role_manipulation(User) should_handle_basic_role_manipulation(Group) should_handle_basic_role_manipulation(UserNoGroup) should "models without groups enabled raise errors when group commands are queried" do @usernogroup = UserNoGroup.create! assert_raises RuntimeError do @usernogroup.groups end end context "group testing: " do setup do @user1 = User.create! @user2 = User.create! @user3 = User.create! @group1 = Group.create! @group2 = Group.create! @group3 = Group.create! @group4 = Group.create! @group5 = Group.create! @foo = Foo.create! @bar = Bar.create! end should "be able to assign users to a group" do @user1.in_group!(@group1) @user2.in_group!(@group1) @user1.in_group!(@group2) assert_same_elements @user1.groups, [@group1, @group2] assert_same_elements @group1.children, [@user1, @user2] assert_equal @group2.children, [@user1] @user1.not_in_group!(@group1) assert_same_elements @user1.groups, [@group2] end context "given test users and groups" do setup do @user1.in_group!(@group1) @group1.in_group!(@group2) @group2.in_group!(@group4) @user1.in_group!(@group3) @user2.in_group!(@group2) end should "avoid circularity" do @group4.in_group!(@group5) assert_raises RuntimeError do @group5.in_group!(@group4) end assert_raises RuntimeError do @group5.in_group!(@group1) end end should "not follow meaningless member assignments" do @group5.has_role!(:member, @user1) assert_equal @group5.children, [] end should "handle nested groups" do assert_same_elements @user1.groups(:nested => false), [@group1, @group3] assert_same_elements @user1.groups, [@group1, @group2, @group3, @group4] assert_same_elements @user2.groups, [@group2, @group4] assert_same_elements @group4.children, [@group2, @group1, @user1, @user2] assert_same_elements @group2.children, [@group1, @user1, @user2] assert @group4.accepts_role?(:member, @user1) assert @group2.accepts_role?(:member, @user1) assert_false @group4.accepts_role?(:member, @user1, :check_groups => false) end should "be able to filter children based on roles" do assert_same_elements @group4.children(:roles => :any), [@group2, @group1, @user1, @user2] assert_same_elements @group4.children(:roles => [:member]), [@group2, @group1, @user1, @user2] assert_same_elements @group4.children(:roles => [:owner]), [] @user3.has_role!(:owner, @group4) assert_same_elements @group4.children(), [@group2, @group1, @user1, @user2] assert_same_elements @group4.children(:roles => :any), [@group2, @group1, @user1, @user2, @user3] assert_same_elements @group4.children(:roles => [:member]), [@group2, @group1, @user1, @user2] assert_same_elements @group4.children(:roles => [:owner]), [@user3] end should "be able to display hashes of subject permissions" do @user3.has_role!(:owner, @group4) assert_equal @group4.children(:roles => :any, :view => :subject_hash), {@group2 => [:member], @group1 => [:member], @user1 => [:member], @user2 => [:member], @user3 => [:owner]} end should "check roles based on groups" do assert @user2.has_role?(:member, @group2) @group2.has_role!(:owner, @foo) assert @user2.has_role?(:owner, @foo) assert_false @user2.has_role?(:owner, @foo, :check_groups => false) assert @user1.has_role?(:owner, @foo) assert_false @user1.has_role?(:owner, @foo, :check_groups => false) assert_same_elements @foo.list_owners, [@group2, @group1, @user1, @user2] assert_same_elements @foo.list_owners(:check_groups => false), [@group2] assert @foo.accepts_role?(:owner, @user1) assert_false @foo.accepts_role?(:owner, @user1, :check_groups => false) end end end end end