import { AdminUser } from '../entities/AdminUser'; import { AuthorizationService } from './AuthorizationService'; describe('AuthorizationService', () => { describe('TDD - Test First', () => { describe('canListUsers', () => { it('should allow owner to list users', () => { // Arrange const owner = AdminUser.create({ id: 'owner-1', email: 'owner@example.com', displayName: 'Owner', roles: ['owner'], status: 'active', }); // Act const canList = AuthorizationService.canListUsers(owner); // Assert expect(canList).toBe(true); }); it('should allow admin to list users', () => { // Arrange const admin = AdminUser.create({ id: 'admin-1', email: 'admin@example.com', displayName: 'Admin', roles: ['admin'], status: 'active', }); // Act const canList = AuthorizationService.canListUsers(admin); // Assert expect(canList).toBe(true); }); it('should deny regular user from listing users', () => { // Arrange const user = AdminUser.create({ id: 'user-1', email: 'user@example.com', displayName: 'User', roles: ['user'], status: 'active', }); // Act const canList = AuthorizationService.canListUsers(user); // Assert expect(canList).toBe(false); }); it('should deny suspended admin from listing users', () => { // Arrange const suspendedAdmin = AdminUser.create({ id: 'admin-1', email: 'admin@example.com', displayName: 'Admin', roles: ['admin'], status: 'suspended', }); // Act const canList = AuthorizationService.canListUsers(suspendedAdmin); // Assert expect(canList).toBe(false); }); it('should allow owner with multiple roles to list users', () => { // Arrange const owner = AdminUser.create({ id: 'owner-1', email: 'owner@example.com', displayName: 'Owner', roles: ['owner'], status: 'active', }); // Act const canList = AuthorizationService.canListUsers(owner); // Assert expect(canList).toBe(true); }); }); describe('canPerformAction with manage', () => { it('should allow owner to manage any user', () => { // Arrange const owner = AdminUser.create({ id: 'owner-1', email: 'owner@example.com', displayName: 'Owner', roles: ['owner'], status: 'active', }); const targetUser = AdminUser.create({ id: 'user-1', email: 'user@example.com', displayName: 'User', roles: ['user'], status: 'active', }); // Act const canManage = AuthorizationService.canPerformAction(owner, 'manage', targetUser); // Assert expect(canManage).toBe(true); }); it('should allow admin to manage non-admin users', () => { // Arrange const admin = AdminUser.create({ id: 'admin-1', email: 'admin@example.com', displayName: 'Admin', roles: ['admin'], status: 'active', }); const targetUser = AdminUser.create({ id: 'user-1', email: 'user@example.com', displayName: 'User', roles: ['user'], status: 'active', }); // Act const canManage = AuthorizationService.canPerformAction(admin, 'manage', targetUser); // Assert expect(canManage).toBe(true); }); it('should deny admin from managing other admins', () => { // Arrange const admin1 = AdminUser.create({ id: 'admin-1', email: 'admin1@example.com', displayName: 'Admin 1', roles: ['admin'], status: 'active', }); const admin2 = AdminUser.create({ id: 'admin-2', email: 'admin2@example.com', displayName: 'Admin 2', roles: ['admin'], status: 'active', }); // Act const canManage = AuthorizationService.canPerformAction(admin1, 'manage', admin2); // Assert expect(canManage).toBe(false); }); it('should deny regular user from managing anyone', () => { // Arrange const user = AdminUser.create({ id: 'user-1', email: 'user@example.com', displayName: 'User', roles: ['user'], status: 'active', }); const targetUser = AdminUser.create({ id: 'user-2', email: 'user2@example.com', displayName: 'User 2', roles: ['user'], status: 'active', }); // Act const canManage = AuthorizationService.canPerformAction(user, 'manage', targetUser); // Assert expect(canManage).toBe(false); }); it('should allow admin to manage suspended users', () => { // Arrange const admin = AdminUser.create({ id: 'admin-1', email: 'admin@example.com', displayName: 'Admin', roles: ['admin'], status: 'active', }); const suspendedUser = AdminUser.create({ id: 'user-1', email: 'user@example.com', displayName: 'User', roles: ['user'], status: 'suspended', }); // Act const canManage = AuthorizationService.canPerformAction(admin, 'manage', suspendedUser); // Assert expect(canManage).toBe(true); }); }); describe('canPerformAction with modify_roles', () => { it('should allow owner to modify roles', () => { // Arrange const owner = AdminUser.create({ id: 'owner-1', email: 'owner@example.com', displayName: 'Owner', roles: ['owner'], status: 'active', }); const targetUser = AdminUser.create({ id: 'user-1', email: 'user@example.com', displayName: 'User', roles: ['user'], status: 'active', }); // Act const canModify = AuthorizationService.canPerformAction(owner, 'modify_roles', targetUser); // Assert expect(canModify).toBe(true); }); it('should deny admin from modifying roles', () => { // Arrange const admin = AdminUser.create({ id: 'admin-1', email: 'admin@example.com', displayName: 'Admin', roles: ['admin'], status: 'active', }); const targetUser = AdminUser.create({ id: 'user-1', email: 'user@example.com', displayName: 'User', roles: ['user'], status: 'active', }); // Act const canModify = AuthorizationService.canPerformAction(admin, 'modify_roles', targetUser); // Assert expect(canModify).toBe(false); }); it('should deny regular user from modifying roles', () => { // Arrange const user = AdminUser.create({ id: 'user-1', email: 'user@example.com', displayName: 'User', roles: ['user'], status: 'active', }); const targetUser = AdminUser.create({ id: 'user-2', email: 'user2@example.com', displayName: 'User 2', roles: ['user'], status: 'active', }); // Act const canModify = AuthorizationService.canPerformAction(user, 'modify_roles', targetUser); // Assert expect(canModify).toBe(false); }); }); describe('canPerformAction with change_status', () => { it('should allow owner to change any status', () => { // Arrange const owner = AdminUser.create({ id: 'owner-1', email: 'owner@example.com', displayName: 'Owner', roles: ['owner'], status: 'active', }); const targetUser = AdminUser.create({ id: 'user-1', email: 'user@example.com', displayName: 'User', roles: ['user'], status: 'active', }); // Act const canChange = AuthorizationService.canPerformAction(owner, 'change_status', targetUser); // Assert expect(canChange).toBe(true); }); it('should allow admin to change non-admin status', () => { // Arrange const admin = AdminUser.create({ id: 'admin-1', email: 'admin@example.com', displayName: 'Admin', roles: ['admin'], status: 'active', }); const targetUser = AdminUser.create({ id: 'user-1', email: 'user@example.com', displayName: 'User', roles: ['user'], status: 'active', }); // Act const canChange = AuthorizationService.canPerformAction(admin, 'change_status', targetUser); // Assert expect(canChange).toBe(true); }); it('should deny admin from changing admin status', () => { // Arrange const admin1 = AdminUser.create({ id: 'admin-1', email: 'admin1@example.com', displayName: 'Admin 1', roles: ['admin'], status: 'active', }); const admin2 = AdminUser.create({ id: 'admin-2', email: 'admin2@example.com', displayName: 'Admin 2', roles: ['admin'], status: 'active', }); // Act const canChange = AuthorizationService.canPerformAction(admin1, 'change_status', admin2); // Assert expect(canChange).toBe(false); }); it('should deny regular user from changing status', () => { // Arrange const user = AdminUser.create({ id: 'user-1', email: 'user@example.com', displayName: 'User', roles: ['user'], status: 'active', }); const targetUser = AdminUser.create({ id: 'user-2', email: 'user2@example.com', displayName: 'User 2', roles: ['user'], status: 'active', }); // Act const canChange = AuthorizationService.canPerformAction(user, 'change_status', targetUser); // Assert expect(canChange).toBe(false); }); }); describe('canPerformAction with delete', () => { it('should allow owner to delete any user', () => { // Arrange const owner = AdminUser.create({ id: 'owner-1', email: 'owner@example.com', displayName: 'Owner', roles: ['owner'], status: 'active', }); const targetUser = AdminUser.create({ id: 'user-1', email: 'user@example.com', displayName: 'User', roles: ['user'], status: 'active', }); // Act const canDelete = AuthorizationService.canPerformAction(owner, 'delete', targetUser); // Assert expect(canDelete).toBe(true); }); it('should allow admin to delete non-admin users', () => { // Arrange const admin = AdminUser.create({ id: 'admin-1', email: 'admin@example.com', displayName: 'Admin', roles: ['admin'], status: 'active', }); const targetUser = AdminUser.create({ id: 'user-1', email: 'user@example.com', displayName: 'User', roles: ['user'], status: 'active', }); // Act const canDelete = AuthorizationService.canPerformAction(admin, 'delete', targetUser); // Assert expect(canDelete).toBe(true); }); it('should deny admin from deleting other admins', () => { // Arrange const admin1 = AdminUser.create({ id: 'admin-1', email: 'admin1@example.com', displayName: 'Admin 1', roles: ['admin'], status: 'active', }); const admin2 = AdminUser.create({ id: 'admin-2', email: 'admin2@example.com', displayName: 'Admin 2', roles: ['admin'], status: 'active', }); // Act const canDelete = AuthorizationService.canPerformAction(admin1, 'delete', admin2); // Assert expect(canDelete).toBe(false); }); it('should deny regular user from deleting anyone', () => { // Arrange const user = AdminUser.create({ id: 'user-1', email: 'user@example.com', displayName: 'User', roles: ['user'], status: 'active', }); const targetUser = AdminUser.create({ id: 'user-2', email: 'user2@example.com', displayName: 'User 2', roles: ['user'], status: 'active', }); // Act const canDelete = AuthorizationService.canPerformAction(user, 'delete', targetUser); // Assert expect(canDelete).toBe(false); }); it('should allow owner to delete suspended users', () => { // Arrange const owner = AdminUser.create({ id: 'owner-1', email: 'owner@example.com', displayName: 'Owner', roles: ['owner'], status: 'active', }); const suspendedUser = AdminUser.create({ id: 'user-1', email: 'user@example.com', displayName: 'User', roles: ['user'], status: 'suspended', }); // Act const canDelete = AuthorizationService.canPerformAction(owner, 'delete', suspendedUser); // Assert expect(canDelete).toBe(true); }); }); describe('getPermissions', () => { it('should return correct permissions for owner', () => { // Arrange const owner = AdminUser.create({ id: 'owner-1', email: 'owner@example.com', displayName: 'Owner', roles: ['owner'], status: 'active', }); // Act const permissions = AuthorizationService.getPermissions(owner); // Assert expect(permissions).toContain('users.view'); expect(permissions).toContain('users.list'); expect(permissions).toContain('users.manage'); expect(permissions).toContain('users.roles.modify'); expect(permissions).toContain('users.status.change'); expect(permissions).toContain('users.create'); expect(permissions).toContain('users.delete'); expect(permissions).toContain('users.export'); }); it('should return correct permissions for admin', () => { // Arrange const admin = AdminUser.create({ id: 'admin-1', email: 'admin@example.com', displayName: 'Admin', roles: ['admin'], status: 'active', }); // Act const permissions = AuthorizationService.getPermissions(admin); // Assert expect(permissions).toContain('users.view'); expect(permissions).toContain('users.list'); expect(permissions).toContain('users.manage'); expect(permissions).toContain('users.status.change'); expect(permissions).toContain('users.create'); expect(permissions).toContain('users.delete'); expect(permissions).not.toContain('users.roles.modify'); expect(permissions).not.toContain('users.export'); }); it('should return empty permissions for regular user', () => { // Arrange const user = AdminUser.create({ id: 'user-1', email: 'user@example.com', displayName: 'User', roles: ['user'], status: 'active', }); // Act const permissions = AuthorizationService.getPermissions(user); // Assert expect(permissions).toEqual([]); }); it('should return empty permissions for suspended admin', () => { // Arrange const suspendedAdmin = AdminUser.create({ id: 'admin-1', email: 'admin@example.com', displayName: 'Admin', roles: ['admin'], status: 'suspended', }); // Act const permissions = AuthorizationService.getPermissions(suspendedAdmin); // Assert expect(permissions).toEqual([]); }); }); describe('hasPermission', () => { it('should return true for owner with users.view permission', () => { // Arrange const owner = AdminUser.create({ id: 'owner-1', email: 'owner@example.com', displayName: 'Owner', roles: ['owner'], status: 'active', }); // Act const hasPermission = AuthorizationService.hasPermission(owner, 'users.view'); // Assert expect(hasPermission).toBe(true); }); it('should return false for admin with users.roles.modify permission', () => { // Arrange const admin = AdminUser.create({ id: 'admin-1', email: 'admin@example.com', displayName: 'Admin', roles: ['admin'], status: 'active', }); // Act const hasPermission = AuthorizationService.hasPermission(admin, 'users.roles.modify'); // Assert expect(hasPermission).toBe(false); }); it('should return false for regular user with any permission', () => { // Arrange const user = AdminUser.create({ id: 'user-1', email: 'user@example.com', displayName: 'User', roles: ['user'], status: 'active', }); // Act const hasPermission = AuthorizationService.hasPermission(user, 'users.view'); // Assert expect(hasPermission).toBe(false); }); }); describe('enforce', () => { it('should not throw for authorized action', () => { // Arrange const owner = AdminUser.create({ id: 'owner-1', email: 'owner@example.com', displayName: 'Owner', roles: ['owner'], status: 'active', }); const targetUser = AdminUser.create({ id: 'user-1', email: 'user@example.com', displayName: 'User', roles: ['user'], status: 'active', }); // Act & Assert - Should not throw expect(() => { AuthorizationService.enforce(owner, 'manage', targetUser); }).not.toThrow(); }); it('should throw for unauthorized action', () => { // Arrange const user = AdminUser.create({ id: 'user-1', email: 'user@example.com', displayName: 'User', roles: ['user'], status: 'active', }); const targetUser = AdminUser.create({ id: 'user-2', email: 'user2@example.com', displayName: 'User 2', roles: ['user'], status: 'active', }); // Act & Assert - Should throw expect(() => { AuthorizationService.enforce(user, 'manage', targetUser); }).toThrow(); }); }); describe('enforcePermission', () => { it('should not throw for authorized permission', () => { // Arrange const owner = AdminUser.create({ id: 'owner-1', email: 'owner@example.com', displayName: 'Owner', roles: ['owner'], status: 'active', }); // Act & Assert - Should not throw expect(() => { AuthorizationService.enforcePermission(owner, 'users.view'); }).not.toThrow(); }); it('should throw for unauthorized permission', () => { // Arrange const admin = AdminUser.create({ id: 'admin-1', email: 'admin@example.com', displayName: 'Admin', roles: ['admin'], status: 'active', }); // Act & Assert - Should throw expect(() => { AuthorizationService.enforcePermission(admin, 'users.roles.modify'); }).toThrow(); }); }); }); });