import 'package:flutter_test/flutter_test.dart'; import 'package:tatlock_ui/core/auth/permissions.dart'; void main() { group('Domain', () { group('fromString', () { test('parses valid domain strings', () { expect(Domain.fromString('control-room'), equals(Domain.controlRoom)); expect(Domain.fromString('library'), equals(Domain.library)); expect(Domain.fromString('media'), equals(Domain.media)); expect(Domain.fromString('ai'), equals(Domain.ai)); expect(Domain.fromString('housekeeper'), equals(Domain.housekeeper)); expect(Domain.fromString('developer'), equals(Domain.developer)); expect(Domain.fromString('documents'), equals(Domain.documents)); expect(Domain.fromString('gaming'), equals(Domain.gaming)); expect(Domain.fromString('admin'), equals(Domain.admin)); }); test('returns null for invalid domain', () { expect(Domain.fromString('invalid'), isNull); expect(Domain.fromString(''), isNull); expect(Domain.fromString('CONTROL-ROOM'), isNull); }); }); test('value returns correct string', () { expect(Domain.controlRoom.value, equals('control-room')); expect(Domain.library.value, equals('library')); expect(Domain.admin.value, equals('admin')); }); }); group('Action', () { group('fromString', () { test('parses valid action strings', () { expect(Action.fromString('viewer'), equals(Action.viewer)); expect(Action.fromString('user'), equals(Action.user)); expect(Action.fromString('editor'), equals(Action.editor)); expect(Action.fromString('admin'), equals(Action.admin)); }); test('returns null for invalid action', () { expect(Action.fromString('invalid'), isNull); expect(Action.fromString(''), isNull); expect(Action.fromString('ADMIN'), isNull); }); }); group('level', () { test('has correct hierarchy levels', () { expect(Action.viewer.level, equals(1)); expect(Action.user.level, equals(2)); expect(Action.editor.level, equals(3)); expect(Action.admin.level, equals(4)); }); test('levels are ordered correctly', () { expect(Action.viewer.level, lessThan(Action.user.level)); expect(Action.user.level, lessThan(Action.editor.level)); expect(Action.editor.level, lessThan(Action.admin.level)); }); }); group('grants', () { test('admin grants all actions', () { expect(Action.admin.grants(Action.admin), isTrue); expect(Action.admin.grants(Action.editor), isTrue); expect(Action.admin.grants(Action.user), isTrue); expect(Action.admin.grants(Action.viewer), isTrue); }); test('editor grants editor and below', () { expect(Action.editor.grants(Action.admin), isFalse); expect(Action.editor.grants(Action.editor), isTrue); expect(Action.editor.grants(Action.user), isTrue); expect(Action.editor.grants(Action.viewer), isTrue); }); test('user grants user and below', () { expect(Action.user.grants(Action.admin), isFalse); expect(Action.user.grants(Action.editor), isFalse); expect(Action.user.grants(Action.user), isTrue); expect(Action.user.grants(Action.viewer), isTrue); }); test('viewer only grants viewer', () { expect(Action.viewer.grants(Action.admin), isFalse); expect(Action.viewer.grants(Action.editor), isFalse); expect(Action.viewer.grants(Action.user), isFalse); expect(Action.viewer.grants(Action.viewer), isTrue); }); }); }); group('Role', () { group('grants', () { test('grants permission for matching domain and category', () { const role = Role( id: '1', name: 'control-room.general:admin', domain: Domain.controlRoom, category: 'general', action: Action.admin, ); expect(role.grants(Domain.controlRoom, Action.admin), isTrue); expect(role.grants(Domain.controlRoom, Action.editor), isTrue); expect(role.grants(Domain.controlRoom, Action.user), isTrue); expect(role.grants(Domain.controlRoom, Action.viewer), isTrue); }); test('denies permission for different domain', () { const role = Role( id: '1', name: 'control-room.general:admin', domain: Domain.controlRoom, category: 'general', action: Action.admin, ); expect(role.grants(Domain.media, Action.viewer), isFalse); expect(role.grants(Domain.library, Action.viewer), isFalse); }); test('denies permission for different category', () { const role = Role( id: '1', name: 'control-room.servers:admin', domain: Domain.controlRoom, category: 'servers', action: Action.admin, ); expect( role.grants(Domain.controlRoom, Action.admin, category: 'general'), isFalse, ); expect( role.grants(Domain.controlRoom, Action.admin, category: 'servers'), isTrue, ); }); test('global admin grants all permissions', () { const globalAdmin = Role( id: '1', name: 'admin.general:admin', domain: Domain.admin, category: 'general', action: Action.admin, ); // Should grant any domain, category, action expect(globalAdmin.grants(Domain.controlRoom, Action.admin), isTrue); expect(globalAdmin.grants(Domain.media, Action.editor), isTrue); expect(globalAdmin.grants(Domain.library, Action.viewer), isTrue); expect( globalAdmin.grants(Domain.documents, Action.user, category: 'specific'), isTrue, ); }); test('non-global admin role does not grant everything', () { const domainAdmin = Role( id: '1', name: 'admin.specific:admin', domain: Domain.admin, category: 'specific', // Not 'general' action: Action.admin, ); // Should not grant arbitrary permissions expect(domainAdmin.grants(Domain.controlRoom, Action.viewer), isFalse); }); }); }); group('RoleListPermissions extension', () { final roles = [ const Role( id: '1', name: 'control-room.general:admin', domain: Domain.controlRoom, category: 'general', action: Action.admin, ), const Role( id: '2', name: 'media.general:viewer', domain: Domain.media, category: 'general', action: Action.viewer, ), ]; group('hasPermission', () { test('returns true when any role grants permission', () { expect( roles.hasPermission(Domain.controlRoom, Action.admin), isTrue, ); expect( roles.hasPermission(Domain.controlRoom, Action.viewer), isTrue, ); expect( roles.hasPermission(Domain.media, Action.viewer), isTrue, ); }); test('returns false when no role grants permission', () { expect( roles.hasPermission(Domain.media, Action.editor), isFalse, ); expect( roles.hasPermission(Domain.library, Action.viewer), isFalse, ); }); test('returns false for empty role list', () { expect( [].hasPermission(Domain.controlRoom, Action.viewer), isFalse, ); }); }); group('isGlobalAdmin', () { test('returns true when global admin role present', () { final adminRoles = [ const Role( id: '1', name: 'admin.general:admin', domain: Domain.admin, category: 'general', action: Action.admin, ), ]; expect(adminRoles.isGlobalAdmin, isTrue); }); test('returns false when no global admin role', () { expect(roles.isGlobalAdmin, isFalse); }); test('returns false for empty role list', () { expect([].isGlobalAdmin, isFalse); }); test('returns false for admin domain with non-general category', () { final limitedAdmin = [ const Role( id: '1', name: 'admin.specific:admin', domain: Domain.admin, category: 'specific', action: Action.admin, ), ]; expect(limitedAdmin.isGlobalAdmin, isFalse); }); test('returns false for admin domain with non-admin action', () { final viewerAdmin = [ const Role( id: '1', name: 'admin.general:viewer', domain: Domain.admin, category: 'general', action: Action.viewer, ), ]; expect(viewerAdmin.isGlobalAdmin, isFalse); }); }); }); }