Les parents doivent pouvoir suivre la scolarité de leurs enfants (notes, emploi du temps, devoirs). Cela nécessite un lien formalisé entre le compte parent et le compte élève, géré par les administrateurs. Le lien est établi soit manuellement via l'interface d'administration, soit automatiquement lors de l'activation du compte parent lorsque l'invitation inclut un élève cible. Ce lien conditionne l'accès aux données scolaires de l'enfant (autorisations vérifiées par un voter dédié).
147 lines
4.2 KiB
PHP
147 lines
4.2 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Tests\Unit\Administration\Infrastructure\Security;
|
|
|
|
use App\Administration\Domain\Model\User\Role;
|
|
use App\Administration\Infrastructure\Security\PeriodVoter;
|
|
use PHPUnit\Framework\Attributes\DataProvider;
|
|
use PHPUnit\Framework\Attributes\Test;
|
|
use PHPUnit\Framework\TestCase;
|
|
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
|
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
|
|
use Symfony\Component\Security\Core\User\UserInterface;
|
|
|
|
final class PeriodVoterTest extends TestCase
|
|
{
|
|
private PeriodVoter $voter;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
$this->voter = new PeriodVoter();
|
|
}
|
|
|
|
#[Test]
|
|
public function itAbstainsForUnrelatedAttributes(): void
|
|
{
|
|
$token = $this->tokenWithRole(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, [PeriodVoter::VIEW]);
|
|
|
|
self::assertSame(Voter::ACCESS_DENIED, $result);
|
|
}
|
|
|
|
// --- VIEW ---
|
|
|
|
#[Test]
|
|
#[DataProvider('viewAllowedRolesProvider')]
|
|
public function itGrantsViewToStaffRoles(string $role): void
|
|
{
|
|
$token = $this->tokenWithRole($role);
|
|
|
|
$result = $this->voter->vote($token, null, [PeriodVoter::VIEW]);
|
|
|
|
self::assertSame(Voter::ACCESS_GRANTED, $result);
|
|
}
|
|
|
|
/**
|
|
* @return iterable<string, array{string}>
|
|
*/
|
|
public static function viewAllowedRolesProvider(): iterable
|
|
{
|
|
yield 'SUPER_ADMIN' => [Role::SUPER_ADMIN->value];
|
|
yield 'ADMIN' => [Role::ADMIN->value];
|
|
yield 'PROF' => [Role::PROF->value];
|
|
yield 'VIE_SCOLAIRE' => [Role::VIE_SCOLAIRE->value];
|
|
yield 'SECRETARIAT' => [Role::SECRETARIAT->value];
|
|
}
|
|
|
|
#[Test]
|
|
#[DataProvider('viewDeniedRolesProvider')]
|
|
public function itDeniesViewToNonStaffRoles(string $role): void
|
|
{
|
|
$token = $this->tokenWithRole($role);
|
|
|
|
$result = $this->voter->vote($token, null, [PeriodVoter::VIEW]);
|
|
|
|
self::assertSame(Voter::ACCESS_DENIED, $result);
|
|
}
|
|
|
|
/**
|
|
* @return iterable<string, array{string}>
|
|
*/
|
|
public static function viewDeniedRolesProvider(): iterable
|
|
{
|
|
yield 'PARENT' => [Role::PARENT->value];
|
|
yield 'ELEVE' => [Role::ELEVE->value];
|
|
}
|
|
|
|
// --- CONFIGURE ---
|
|
|
|
#[Test]
|
|
#[DataProvider('configureAllowedRolesProvider')]
|
|
public function itGrantsConfigureToAdminRoles(string $role): void
|
|
{
|
|
$token = $this->tokenWithRole($role);
|
|
|
|
$result = $this->voter->vote($token, null, [PeriodVoter::CONFIGURE]);
|
|
|
|
self::assertSame(Voter::ACCESS_GRANTED, $result);
|
|
}
|
|
|
|
/**
|
|
* @return iterable<string, array{string}>
|
|
*/
|
|
public static function configureAllowedRolesProvider(): iterable
|
|
{
|
|
yield 'SUPER_ADMIN' => [Role::SUPER_ADMIN->value];
|
|
yield 'ADMIN' => [Role::ADMIN->value];
|
|
}
|
|
|
|
#[Test]
|
|
#[DataProvider('configureDeniedRolesProvider')]
|
|
public function itDeniesConfigureToNonAdminRoles(string $role): void
|
|
{
|
|
$token = $this->tokenWithRole($role);
|
|
|
|
$result = $this->voter->vote($token, null, [PeriodVoter::CONFIGURE]);
|
|
|
|
self::assertSame(Voter::ACCESS_DENIED, $result);
|
|
}
|
|
|
|
/**
|
|
* @return iterable<string, array{string}>
|
|
*/
|
|
public static function configureDeniedRolesProvider(): iterable
|
|
{
|
|
yield 'PROF' => [Role::PROF->value];
|
|
yield 'VIE_SCOLAIRE' => [Role::VIE_SCOLAIRE->value];
|
|
yield 'SECRETARIAT' => [Role::SECRETARIAT->value];
|
|
yield 'PARENT' => [Role::PARENT->value];
|
|
yield 'ELEVE' => [Role::ELEVE->value];
|
|
}
|
|
|
|
private function tokenWithRole(string $role): TokenInterface
|
|
{
|
|
$user = $this->createMock(UserInterface::class);
|
|
$user->method('getRoles')->willReturn([$role]);
|
|
|
|
$token = $this->createMock(TokenInterface::class);
|
|
$token->method('getUser')->willReturn($user);
|
|
|
|
return $token;
|
|
}
|
|
}
|