getId()); self::assertSame('custom', $role->getCode()); self::assertSame('Custom', $role->getLabel()); self::assertNull($role->getDescription()); self::assertFalse($role->isSystem()); self::assertTrue($role->getPermissions()->isEmpty()); } public function testAddPermissionAddsOnce(): void { $role = new Role('custom', 'Custom'); $permission = new Permission('core.users.view', 'Voir', 'core'); $role->addPermission($permission); $role->addPermission($permission); self::assertSame(1, $role->getPermissions()->count()); } public function testAddPermissionAddsMultipleDistinct(): void { $role = new Role('custom', 'Custom'); $permissionView = new Permission('core.users.view', 'Voir', 'core'); $permissionEdit = new Permission('core.users.edit', 'Editer', 'core'); $role->addPermission($permissionView); $role->addPermission($permissionEdit); self::assertSame(2, $role->getPermissions()->count()); } public function testRemovePermissionRemovesWhenPresent(): void { $role = new Role('custom', 'Custom'); $permission = new Permission('core.users.view', 'Voir', 'core'); $role->addPermission($permission); $role->removePermission($permission); self::assertSame(0, $role->getPermissions()->count()); } public function testRemovePermissionIsNoOpWhenAbsent(): void { $role = new Role('custom', 'Custom'); $permission = new Permission('core.users.view', 'Voir', 'core'); $role->removePermission($permission); self::assertSame(0, $role->getPermissions()->count()); } public function testEnsureDeletableAllowsNonSystemRole(): void { $role = new Role('custom', 'Custom', false); $role->ensureDeletable(); $this->expectNotToPerformAssertions(); } public function testEnsureDeletableThrowsForSystemRole(): void { $role = new Role('admin', 'Admin', true); $this->expectException(SystemRoleDeletionException::class); $this->expectExceptionMessage('admin'); $role->ensureDeletable(); } }