diff --git a/spec/models/permission_spec.rb b/spec/models/permission_spec.rb new file mode 100644 index 000000000..af15f6bc9 --- /dev/null +++ b/spec/models/permission_spec.rb @@ -0,0 +1,18 @@ +require 'rails_helper' + +RSpec.describe Permission, type: :model do + describe '.with_parents' do + context 'when given a simple string (no dots)' do + it 'returns an array containing only that string' do + expect(Permission.with_parents('foo')).to eq(['foo']) + end + end + + context 'when given a String permission name (dot-delimited identifier)' do + it 'returns an array of String ancestors (desc. from root)' do + expect(Permission.with_parents('foo.bar.baz')) + .to eq(%w[foo foo.bar foo.bar.baz]) + end + end + end +end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 93fd0233e..3e395f3c2 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -454,6 +454,147 @@ RSpec.describe User, type: :model do end end end + + describe '#permissions?' do + subject(:user) { create(:user, roles: [role]) } + let(:role) { create(:role, permissions: [permission]) } + let(:permission) { create(:permission, name: permission_name) } + + context 'with privileges for a root permission (e.g., "foo", not "foo.bar")' do + let(:permission_name) { 'foo' } + + context 'when given that exact permission' do + it 'returns true' do + expect(user.permissions?('foo')).to be(true) + end + end + + context 'when given a sub-permission (i.e., child permission)' do + let(:subpermission) { create(:permission, name: 'foo.bar') } + + context 'that exists' do + before { subpermission } + + it 'returns true' do + expect(user.permissions?('foo.bar')).to be(true) + end + end + + context 'that is inactive' do + before { subpermission.update(active: false) } + + it 'returns false' do + expect(user.permissions?('foo.bar')).to be(false) + end + end + + context 'that does not exist' do + it 'returns true' do + expect(user.permissions?('foo.bar')).to be(true) + end + end + end + + context 'when given a glob' do + context 'matching that permission' do + it 'returns true' do + expect(user.permissions?('foo.*')).to be(true) + end + end + + context 'NOT matching that permission' do + it 'returns false' do + expect(user.permissions?('bar.*')).to be(false) + end + end + end + end + + context 'with privileges for a sub-permission (e.g., "foo.bar", not "foo")' do + let(:permission_name) { 'foo.bar' } + + context 'when given that exact sub-permission' do + it 'returns true' do + expect(user.permissions?('foo.bar')).to be(true) + end + + context 'but the permission is inactive' do + before { permission.update(active: false) } + + it 'returns false' do + expect(user.permissions?('foo.bar')).to be(false) + end + end + end + + context 'when given a sibling sub-permission' do + let(:sibling_permission) { create(:permission, name: 'foo.baz') } + + context 'that exists' do + before { sibling_permission } + + it 'returns false' do + expect(user.permissions?('foo.baz')).to be(false) + end + end + + context 'that does not exist' do + it 'returns false' do + expect(user.permissions?('foo.baz')).to be(false) + end + end + end + + context 'when given the parent permission' do + it 'returns false' do + expect(user.permissions?('foo')).to be(false) + end + end + + context 'when given a glob' do + context 'matching that sub-permission' do + it 'returns true' do + expect(user.permissions?('foo.*')).to be(true) + end + + context 'but the permission is inactive' do + before { permission.update(active: false) } + + it 'returns false' do + expect(user.permissions?('foo.bar')).to be(false) + end + end + end + + context 'NOT matching that sub-permission' do + it 'returns false' do + expect(user.permissions?('bar.*')).to be(false) + end + end + end + end + end + + describe '#permissions_with_child_ids' do + context 'with privileges for a root permission (e.g., "foo", not "foo.bar")' do + subject(:user) { create(:user, roles: [role]) } + let(:role) { create(:role, permissions: [permission]) } + let!(:permission) { create(:permission, name: 'foo') } + let!(:child_permission) { create(:permission, name: 'foo.bar') } + let!(:inactive_child_permission) { create(:permission, name: 'foo.baz', active: false) } + + it 'includes the IDs of user’s explicit permissions' do + expect(user.permissions_with_child_ids) + .to include(permission.id) + end + + it 'includes the IDs of user’s active sub-permissions' do + expect(user.permissions_with_child_ids) + .to include(child_permission.id) + .and not_include(inactive_child_permission.id) + end + end + end end describe 'Attributes:' do diff --git a/test/unit/permission_test.rb b/test/unit/permission_test.rb deleted file mode 100644 index b5337123d..000000000 --- a/test/unit/permission_test.rb +++ /dev/null @@ -1,169 +0,0 @@ -require 'test_helper' - -class PermissionTest < ActiveSupport::TestCase - - test 'permission' do - permissions = Permission.with_parents('some_key.sub_key') - assert_equal('some_key', permissions[0]) - assert_equal('some_key.sub_key', permissions[1]) - assert_equal(2, permissions.count) - end - - test 'user permission' do - - permission1 = Permission.create_or_update( - name: 'admin.permission1', - note: 'Admin Interface', - preferences: {}, - active: true, - ) - permission2 = Permission.create_or_update( - name: 'admin.permission2', - note: 'Admin Interface', - preferences: {}, - active: true, - ) - role_permission1 = Role.create_or_update( - name: 'AdminPermission1', - note: 'To configure your permission1.', - preferences: { - not: ['Customer'], - }, - default_at_signup: false, - updated_by_id: 1, - created_by_id: 1, - ) - role_permission1.permission_revoke('admin') - role_permission1.permission_grant('admin.permission1') - user_with_permission1 = User.create_or_update( - login: 'setting-permission1', - firstname: 'Setting', - lastname: 'Admin Permission1', - email: 'setting-admin-permission1@example.com', - password: 'some_pw', - active: true, - roles: [role_permission1], - updated_by_id: 1, - created_by_id: 1, - ) - - assert_equal(true, user_with_permission1.permissions?('admin.permission1')) - assert_equal(true, user_with_permission1.permissions?('admin.*')) - assert_equal(false, user_with_permission1.permissions?('admi.*')) - assert_equal(false, user_with_permission1.permissions?('admin.permission2')) - assert_equal(false, user_with_permission1.permissions?('admin')) - - permission1.active = false - permission1.save! - - assert_equal(false, user_with_permission1.permissions?('admin.permission1')) - assert_equal(false, user_with_permission1.permissions?('admin.*')) - assert_equal(false, user_with_permission1.permissions?('admi.*')) - assert_equal(false, user_with_permission1.permissions?('admin.permission2')) - assert_equal(false, user_with_permission1.permissions?('admin')) - - role_permission1.permission_grant('admin') - - assert_equal(false, user_with_permission1.permissions?('admin.permission1')) - assert_equal(true, user_with_permission1.permissions?('admin.*')) - assert_equal(false, user_with_permission1.permissions?('admi.*')) - assert_equal(true, user_with_permission1.permissions?('admin.permission2')) - assert_equal(true, user_with_permission1.permissions?('admin')) - - role_permission1.permission_revoke('admin') - - end - - test 'user permission with invalid role' do - - permission3 = Permission.create_or_update( - name: 'admin.permission3', - note: 'Admin Interface', - preferences: {}, - active: true, - ) - role_permission3 = Role.create_or_update( - name: 'AdminPermission2', - note: 'To configure your permission3.', - preferences: { - not: ['Customer'], - }, - default_at_signup: false, - active: true, - updated_by_id: 1, - created_by_id: 1, - ) - role_permission3.permission_grant('admin.permission3') - user_with_permission3 = User.create_or_update( - login: 'setting-permission3', - firstname: 'Setting', - lastname: 'Admin Permission2', - email: 'setting-admin-permission3@example.com', - password: 'some_pw', - active: true, - roles: [role_permission3], - updated_by_id: 1, - created_by_id: 1, - ) - assert_equal(true, user_with_permission3.permissions?('admin.permission3')) - assert_equal(true, user_with_permission3.permissions?('admin.*')) - assert_equal(false, user_with_permission3.permissions?('admi.*')) - assert_equal(false, user_with_permission3.permissions?('admin.permission4')) - assert_equal(false, user_with_permission3.permissions?('admin')) - - role_permission3.active = false - role_permission3.save - user_with_permission3.reload - assert_equal(false, user_with_permission3.permissions?('admin.permission3')) - assert_equal(false, user_with_permission3.permissions?('admin.*')) - assert_equal(false, user_with_permission3.permissions?('admi.*')) - assert_equal(false, user_with_permission3.permissions?('admin.permission4')) - assert_equal(false, user_with_permission3.permissions?('admin')) - - end - - test 'user permission with childs' do - - permission1 = Permission.create_or_update( - name: 'admin.permission_child1', - note: 'Admin Interface', - preferences: {}, - active: true, - ) - permission2 = Permission.create_or_update( - name: 'admin.permission_child2', - note: 'Admin Interface', - preferences: {}, - active: false, - ) - role_permission1 = Role.create_or_update( - name: 'AdminPermissionChild1', - note: 'To configure your permission child1.', - preferences: { - not: ['Customer'], - }, - default_at_signup: false, - updated_by_id: 1, - created_by_id: 1, - ) - role_permission1.permission_grant('admin') - user_with_permission1 = User.create_or_update( - login: 'setting-permission-child1', - firstname: 'Setting', - lastname: 'Admin Permission Child1', - email: 'setting-admin-permission-child1@example.com', - password: 'some_pw', - active: true, - roles: [role_permission1], - updated_by_id: 1, - created_by_id: 1, - ) - assert(user_with_permission1.permissions_with_child_ids.include?(permission1.id)) - assert_not(user_with_permission1.permissions_with_child_ids.include?(permission2.id)) - assert(user_with_permission1.permissions_with_child_ids.include?(Permission.find_by(name: 'admin').id)) - - # cleanup - user_with_permission1.destroy - role_permission1.destroy - end -end