voter = new StudentVoter(); } #[Test] public function itAbstainsForUnrelatedAttributes(): void { $token = $this->tokenWithSecurityUser(Role::ADMIN->value); $result = $this->voter->vote($token, null, ['SOME_OTHER_ATTRIBUTE']); self::assertSame(Voter::ACCESS_ABSTAIN, $result); } #[Test] public function itDeniesAccessToUnauthenticatedUsers(): void { $token = $this->createMock(TokenInterface::class); $token->method('getUser')->willReturn(null); $result = $this->voter->vote($token, null, [StudentVoter::VIEW]); self::assertSame(Voter::ACCESS_DENIED, $result); } #[Test] public function itDeniesAccessToNonSecurityUserInstances(): void { $user = $this->createMock(UserInterface::class); $user->method('getRoles')->willReturn([Role::ADMIN->value]); $token = $this->createMock(TokenInterface::class); $token->method('getUser')->willReturn($user); $result = $this->voter->vote($token, null, [StudentVoter::VIEW]); self::assertSame(Voter::ACCESS_DENIED, $result); } // --- VIEW --- #[Test] #[DataProvider('allowedRolesProvider')] public function itGrantsViewToAllowedRoles(string $role): void { $token = $this->tokenWithSecurityUser($role); $result = $this->voter->vote($token, null, [StudentVoter::VIEW]); self::assertSame(Voter::ACCESS_GRANTED, $result); } #[Test] #[DataProvider('deniedRolesProvider')] public function itDeniesViewToOtherRoles(string $role): void { $token = $this->tokenWithSecurityUser($role); $result = $this->voter->vote($token, null, [StudentVoter::VIEW]); self::assertSame(Voter::ACCESS_DENIED, $result); } // --- CREATE --- #[Test] #[DataProvider('allowedRolesProvider')] public function itGrantsCreateToAllowedRoles(string $role): void { $token = $this->tokenWithSecurityUser($role); $result = $this->voter->vote($token, null, [StudentVoter::CREATE]); self::assertSame(Voter::ACCESS_GRANTED, $result); } #[Test] #[DataProvider('deniedRolesProvider')] public function itDeniesCreateToOtherRoles(string $role): void { $token = $this->tokenWithSecurityUser($role); $result = $this->voter->vote($token, null, [StudentVoter::CREATE]); self::assertSame(Voter::ACCESS_DENIED, $result); } // --- MANAGE --- #[Test] #[DataProvider('allowedRolesProvider')] public function itGrantsManageToAllowedRoles(string $role): void { $token = $this->tokenWithSecurityUser($role); $result = $this->voter->vote($token, null, [StudentVoter::MANAGE]); self::assertSame(Voter::ACCESS_GRANTED, $result); } #[Test] #[DataProvider('deniedRolesProvider')] public function itDeniesManageToOtherRoles(string $role): void { $token = $this->tokenWithSecurityUser($role); $result = $this->voter->vote($token, null, [StudentVoter::MANAGE]); self::assertSame(Voter::ACCESS_DENIED, $result); } // --- Data Providers --- /** * @return iterable */ public static function allowedRolesProvider(): iterable { yield 'SUPER_ADMIN' => [Role::SUPER_ADMIN->value]; yield 'ADMIN' => [Role::ADMIN->value]; yield 'SECRETARIAT' => [Role::SECRETARIAT->value]; } /** * @return iterable */ public static function deniedRolesProvider(): iterable { yield 'PROF' => [Role::PROF->value]; yield 'VIE_SCOLAIRE' => [Role::VIE_SCOLAIRE->value]; yield 'PARENT' => [Role::PARENT->value]; yield 'ELEVE' => [Role::ELEVE->value]; } private function tokenWithSecurityUser(string $role): TokenInterface { $securityUser = new SecurityUser( UserId::fromString('550e8400-e29b-41d4-a716-446655440010'), 'test@example.com', 'hashed_password', TenantId::fromString(self::TENANT_ID), [$role], ); $token = $this->createMock(TokenInterface::class); $token->method('getUser')->willReturn($securityUser); return $token; } }