store = new InMemoryActiveRoleStore(); $this->roleContext = new RoleContext($this->store); } #[Test] public function itReturnsPrimaryRoleWhenNoActiveRoleStored(): void { $user = $this->createUser(Role::PROF); self::assertSame(Role::PROF, $this->roleContext->getActiveRole($user)); } #[Test] public function itSwitchesToAnotherRole(): void { $user = $this->createActiveUser(Role::PROF); $user->attribuerRole(Role::ADMIN, new DateTimeImmutable()); $this->roleContext->switchTo($user, Role::ADMIN); self::assertSame(Role::ADMIN, $this->roleContext->getActiveRole($user)); } #[Test] public function itThrowsWhenSwitchingToUnassignedRole(): void { $user = $this->createActiveUser(Role::PROF); $this->expectException(RoleNonAttribueException::class); $this->roleContext->switchTo($user, Role::ADMIN); } #[Test] public function itClearsActiveRole(): void { $user = $this->createActiveUser(Role::PROF); $user->attribuerRole(Role::ADMIN, new DateTimeImmutable()); $this->roleContext->switchTo($user, Role::ADMIN); $this->roleContext->clear($user); self::assertSame(Role::PROF, $this->roleContext->getActiveRole($user)); } #[Test] public function itThrowsWhenAccountIsNotActive(): void { $user = $this->createActiveUser(Role::PROF); $user->attribuerRole(Role::ADMIN, new DateTimeImmutable()); $user->bloquer('Test', new DateTimeImmutable()); $this->expectException(DomainException::class); $this->roleContext->switchTo($user, Role::ADMIN); } private function createUser(Role $role): User { return User::creer( email: new Email('user@example.com'), role: $role, tenantId: TenantId::fromString(self::TENANT_ID), schoolName: 'École Test', dateNaissance: null, createdAt: new DateTimeImmutable('2026-01-15 10:00:00'), ); } private function createActiveUser(Role $role): User { return User::reconstitute( id: UserId::generate(), email: new Email('active@example.com'), roles: [$role], tenantId: TenantId::fromString(self::TENANT_ID), schoolName: 'École Test', statut: StatutCompte::ACTIF, dateNaissance: null, createdAt: new DateTimeImmutable('2026-01-15 10:00:00'), hashedPassword: 'hashed', activatedAt: new DateTimeImmutable('2026-01-16 10:00:00'), consentementParental: null, ); } } /** * @internal */ final class InMemoryActiveRoleStore implements ActiveRoleStore { /** @var array */ private array $roles = []; public function store(User $user, Role $role): void { $this->roles[(string) $user->id] = $role; } public function get(User $user): ?Role { return $this->roles[(string) $user->id] ?? null; } public function clear(User $user): void { unset($this->roles[(string) $user->id]); } }