Project

General

Profile

Download (15.6 KB) Statistics
| Branch: | Tag: | Revision:
# redMine - project management software
# Copyright (C) 2006-2008 Jean-Philippe Lang
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

require "test_helper"

class RoleTest < ActiveSupport::TestCase
should have_many(:user_roles)
should validate_presence_of(:name)
should validate_uniqueness_of(:name)
should allow_value('a role name').for(:name)
should allow_value('トメル34;。').for(:name)
should allow_value('test@example.com').for(:name)

it "should strip leading space on name" do
role = Role.new(:name => " a role name")
role.must_be :valid?
end

it "should strip a trailing space on name" do
role = Role.new(:name => "a role name ")
role.must_be :valid?
end

it "should delete role who has users" do
role = Role.create(:name => 'First')
user = FactoryBot.create(:user)
role.users = [user]
assert_difference('Role.count', -1) do
role.destroy
end
end

it "should detect extra permissions" do
role = roles(:manage_hosts)
assert_equal [:create_hosts, :view_hosts], role.extra_permissions([:destroy_hosts, :edit_hosts, :create_architectures]).sort
end

it "should detect missing permissions" do
role = roles(:manage_hosts)
assert_equal [:create_architectures, :view_architectures], role.missing_permissions([:view_hosts, :view_architectures, :create_architectures]).sort
end

context 'locked roles' do
it "should not rename locked role" do
manager = Role.find_by :name => "Manager"
manager.name = "Renamed Manager"
refute manager.save
assert_equal "This role is locked from being modified by users.", manager.errors.messages[:base].first
end

it "should rename locked role when required" do
manager = Role.find_by :name => "Manager"
manager.name = "Renamed Manager"
manager.modify_locked = true
assert manager.save
end

it "should not modify locked role permissions" do
viewer = Role.find_by :name => "Viewer"
viewer.add_permissions [:create_hosts]
refute viewer.valid?
assert_equal "is locked for user modifications.", viewer.errors.messages.values.first.first
end

it "should modify locked role permissions when required" do
viewer = Role.find_by :name => "Viewer"
viewer.modify_locked = true
viewer.add_permissions [:create_hosts]
assert viewer.valid?
end

it "should modify role using ignore_locking method" do
viewer = Role.find_by :name => "Viewer"
viewer.ignore_locking do |role|
role.name = "Changed Viewer"
role.save!
end
assert Role.find_by(:name => "Changed Viewer")
refute Role.find_by(:name => "Viewer")
end

it "should be givable even when locked" do
user = FactoryBot.create(:user)
role = roles(:viewer)
assert role.locked?
user.roles << role
assert user.save
end

# Using 'def' to ensure bypass_locking is disabled after the test
def test_allow_to_modify_roles_when_bypass_locking
assert roles(:manager).locked?
Role.ignore_locking do
viewer = roles(:viewer)
viewer.add_permissions [:create_hosts]
assert viewer.valid?
end
end
end

describe "Cloning" do
let(:role) { FactoryBot.create(:role) }
let(:cloned_role) do
cloned_role = role.clone
cloned_role.name = "Clone of #{role.name}"
cloned_role.save!
cloned_role
end

it "cloned role keeps link to origin" do
assert_equal role, cloned_role.cloned_from
end

it "allows me to find all roles that were cloned from origin" do
another_role = FactoryBot.create(:role)
cloned_role # enforce lazy let to create the cloned role and role
clones = role.cloned_roles
assert_include clones, cloned_role
assert_not_include clones, another_role
end

it 'nullifies the relation when origin is deleted' do
cloned_role # enforce lazy let to create the cloned role and role
assert role.destroy
cloned_role.reload
assert_nil cloned_role.cloned_from
end

it 'can be found by cloned scope' do
cloned_role # enforce lazy let to create the cloned role and role
assert_include Role.cloned, cloned_role
assert_not_include Role.cloned, role
end
end

context "System roles" do
should "return the default role" do
role = Role.default
assert role.builtin?
assert_equal Role::BUILTIN_DEFAULT_ROLE, role.builtin
end

context "with a missing default role" do
setup do
role_ids = Role.where("builtin = #{Role::BUILTIN_DEFAULT_ROLE}").pluck(:id)
UserRole.where(:role_id => role_ids).destroy_all
roles = Role.where(:id => role_ids)
roles.each do |found_role|
found_role.ignore_locking do |r|
r.filters.destroy_all
r.delete
end
end
end

should "create a new default role" do
assert_difference('Role.count') do
Role.default
end
end

should "return the default role" do
role = Role.default
assert role.builtin?
assert_equal Role::BUILTIN_DEFAULT_ROLE, role.builtin
end
end
end

describe ".for_current_user" do
context "there are two roles, one of them is assigned to current user" do
let(:first) { Role.create(:name => 'First') }
let(:second) { Role.create(:name => 'Second') }
before do
users(:one).roles << first
User.current = users(:one)
end

subject { Role.for_current_user.to_a }
it { subject.must_include(first) }
it { subject.wont_include(second) }
end

context "when current user is admin for_current_user should return all roles" do
setup do
User.current = users(:admin)
end

test "Admin user should query Role model with no restrictions" do
Role.expects(:where).with('0 = 0')
Role.for_current_user
end
end
end

describe ".permissions=" do
let(:role) { FactoryBot.build_stubbed(:role) }

it 'accepts not unique list of permissions' do
role.expects(:add_permissions).once.with(['a', 'b'])
role.permissions = [
FactoryBot.build_stubbed(:permission, :name => 'a'),
FactoryBot.build_stubbed(:permission, :name => 'b'),
FactoryBot.build_stubbed(:permission, :name => 'a'),
FactoryBot.build_stubbed(:permission, :name => 'b')
]
end
end

describe "#add_permissions" do
setup do
@permission1 = FactoryBot.create(:permission, :name => 'permission1')
@permission2 = FactoryBot.create(:permission, :architecture, :name => 'permission2')
@role = FactoryBot.build_stubbed(:role, :permissions => [])
end

it 'should fetch the appropriate permissions' do
assert_equal 2, @role.send(:permission_records, [[@permission1.name, @permission2.name]]).size
end

it "should build filters with assigned permission" do
@role.add_permissions [@permission1.name, @permission2.name.to_sym]
assert @role.filters.all?(&:unlimited?)
permissions = @role.filters.map { |f| f.filterings.map(&:permission) }.flatten
assert_equal 2, @role.filters.size
assert_includes permissions, Permission.find_by_name(@permission1.name)
assert_includes permissions, Permission.find_by_name(@permission2.name)
# not saved yet
assert_empty @role.permissions
end

it "should raise error when given permission does not exist" do
assert_raises ::Foreman::PermissionMissingException do
@role.add_permissions ['does_not_exist']
end
end

it "accespts one permissions instead of array as well" do
@role.add_permissions @permission1.name
permissions = @role.filters.map { |f| f.filterings.map(&:permission) }.flatten

assert_equal 1, @role.filters.size
assert_includes permissions, Permission.find_by_name(@permission1.name)
end

it "sets search filter to all filters" do
search = "id = 1"
@role.add_permissions [@permission1.name, @permission2.name.to_sym], :search => search
refute @role.filters.any?(&:unlimited?)
assert @role.filters.all? { |f| f.search == search }
end
end

describe "#add_permissions!" do
setup do
@permission1 = FactoryBot.create(:permission, :name => 'permission1')
@permission2 = FactoryBot.create(:permission, :architecture, :name => 'permission2')
@role = FactoryBot.build(:role, :permissions => [])
end

it "persists built permissions" do
assert @role.add_permissions!([@permission1.name, @permission2.name.to_sym])
@role.reload

permissions = @role.permissions
assert_equal 2, @role.filters.size
assert_includes permissions, Permission.find_by_name(@permission1.name)
assert_includes permissions, Permission.find_by_name(@permission2.name)
end

it "should add permission to an existing filter" do
role = roles(:destroy_hosts)
assert_equal 1, role.permissions.count
role.add_permissions!([:create_hosts])
assert_equal 2, role.permissions.count
assert_equal 1, role.filters.count
end

it "should add permissions to a newly created filter" do
role = roles(:destroy_hosts)
assert_equal 1, role.permissions.count
role.add_permissions!([:create_architectures])
assert_equal 2, role.permissions.count
assert_equal 2, role.filters.count
end

it "should not duplicate existing filterings" do
role = roles(:create_hosts)
permissions = [:view_architectures]
role.add_permissions!(permissions)
filterings = Filtering.where(:filter_id => Filter.where(:role_id => role.id))
role.add_permissions!(permissions)
assert_equal filterings.count, Filtering.where(:filter_id => Filter.where(:role_id => role.id)).count
end
end

describe "#remove_permissions!" do
it "should remove permissions from role" do
role = roles(:manage_hosts)
assert role.permission_symbols.include?(:create_hosts)
assert role.permission_symbols.include?(:view_hosts)
assert role.permission_symbols.include?(:edit_hosts)
role.remove_permissions!(:view_hosts, :create_hosts)
role.reload
refute role.permission_symbols.include?(:create_hosts)
refute role.permission_symbols.include?(:view_hosts)
assert role.permission_symbols.include?(:edit_hosts)
end

it "should remove filters when removing all permissions" do
role = roles(:manage_hosts)
perms = [:view_hosts, :create_hosts, :edit_hosts, :destroy_hosts]
role.remove_permissions!(*perms)
role.reload
assert_empty role.filters
end
end

context 'having role with filters' do
setup do
@permission1 = FactoryBot.create(:permission, :domain, :name => 'permission1')
@permission2 = FactoryBot.create(:permission, :architecture, :name => 'permission2')
@role = FactoryBot.build(:role, :permissions => [])
@role.add_permissions! [@permission1.name, @permission2.name]
@org1 = FactoryBot.create(:organization)
@org2 = FactoryBot.create(:organization)
@role.filters.reload
@filter_with_org = @role.filters.detect { |f| f.allows_organization_filtering? }
@filter_without_org = @role.filters.detect { |f| !f.allows_organization_filtering? }
end

describe '#sync_inheriting_filters' do
it 'automatically propagates taxonomies to filters after save' do
@role.organizations = [ @org1 ]
@role.save
@filter_with_org.reload
assert_equal [ @org1 ], @filter_with_org.organizations
end

it 'automatically propagates taxonomies only to inheriting filters' do
@filter_with_org.update_attribute :override, true
@role.organizations = [ @org2 ]
@role.save
@filter_with_org.reload
assert_empty @filter_with_org.organizations
end

it 'should forced unlimited check if role or filter have no taxonomies' do
@role.organizations = [ @org1 ]
@role.save
@filter_with_org.reload
assert @filter_without_org.unlimited?
refute @filter_with_org.unlimited?
@role.organizations = []
@role.save
@filter_with_org.reload
assert @filter_without_org.unlimited?
assert @filter_with_org.unlimited?
end

it 'should rollback when invalid filter was saved' do
role = FactoryBot.build(:role)
role.add_permissions! :view_domains
invalid_filter = role.filters.first
invalid_filter.permissions << Permission.where(:name => 'view_subnets')
invalid_filter.save(:validate => false)
refute role.save
assert role.errors[:base].include? "One or more of the associated filters are invalid which prevented the role to be saved"
end

it 'does not touch filters that do not support taxonomies' do
@role.organizations = [ @org1 ]
@role.save
@filter_without_org.reload
assert_empty @filter_without_org.organizations
assert_nil @filter_without_org.taxonomy_search
end

it 'does not touch filters that do not support taxonomies even if they override' do
@filter_without_org.update_attribute :override, true
@role.organizations = [ @org1 ]
@role.save
@filter_without_org.reload
assert_empty @filter_without_org.organizations
assert_nil @filter_without_org.taxonomy_search
end
end

describe '#disable_filters_overriding' do
it 'disables overriding and inherits taxonomies' do
@filter_with_org.update_attribute :override, true
@role.organizations = [ @org1 ]
as_admin do
@role.disable_filters_overriding
@filter_with_org.reload
assert_equal [ @org1 ], @filter_with_org.organizations
refute @filter_with_org.override
end
end
end

describe '#search_by_permission' do
setup do
@domain_permission = FactoryBot.create(:permission, :domain, :name => 'view_test_domain')
@arch_permission = FactoryBot.create(:permission, :architecture, :name => 'view_test_arch')
@role = FactoryBot.build(:role, :permissions => [])
@role.add_permissions! [@domain_permission.name, @arch_permission.name]
end

it 'returns matched roles using equal operator on permission' do
results = Role.search_for('permission = view_test_domain')
assert_includes results, @role
end

it 'allows filtering roles using not equal operator on permission' do
results = Role.search_for('permission != view_test_arch')
refute_includes results, @role
end

it 'empty result if no matched permission found using LIKE operator' do
results = Role.search_for('permission ~ not')
assert_empty results
end

it 'non-empty result if matched permission found using LIKE operator' do
results = Role.search_for('permission ~ test_arch')
refute_empty results
end

it 'allows filtering roles using not in operator on permission' do
results = Role.search_for('permission !^ view_test_arch')
refute_includes results, @role
end
end
end
end
(50-50/67)