feat: Liaison parents-enfants avec gestion des tuteurs
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é).
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Tests\Unit\Administration\Application\Query\GetStudentsForParent;
|
||||
|
||||
use App\Administration\Application\Query\GetStudentsForParent\GetStudentsForParentHandler;
|
||||
use App\Administration\Application\Query\GetStudentsForParent\GetStudentsForParentQuery;
|
||||
use App\Administration\Application\Query\GetStudentsForParent\StudentForParentDto;
|
||||
use App\Administration\Domain\Model\StudentGuardian\RelationshipType;
|
||||
use App\Administration\Domain\Model\StudentGuardian\StudentGuardian;
|
||||
use App\Administration\Domain\Model\User\Email;
|
||||
use App\Administration\Domain\Model\User\Role;
|
||||
use App\Administration\Domain\Model\User\User;
|
||||
use App\Administration\Domain\Model\User\UserId;
|
||||
use App\Administration\Domain\Repository\UserRepository;
|
||||
use App\Administration\Infrastructure\Persistence\InMemory\InMemoryStudentGuardianRepository;
|
||||
use App\Shared\Domain\Tenant\TenantId;
|
||||
use DateTimeImmutable;
|
||||
use PHPUnit\Framework\Attributes\Test;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
final class GetStudentsForParentHandlerTest extends TestCase
|
||||
{
|
||||
private const string TENANT_ID = '550e8400-e29b-41d4-a716-446655440001';
|
||||
private const string STUDENT_1_ID = '550e8400-e29b-41d4-a716-446655440002';
|
||||
private const string STUDENT_2_ID = '550e8400-e29b-41d4-a716-446655440003';
|
||||
private const string GUARDIAN_ID = '550e8400-e29b-41d4-a716-446655440004';
|
||||
|
||||
private InMemoryStudentGuardianRepository $repository;
|
||||
private GetStudentsForParentHandler $handler;
|
||||
private User $studentUser;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->repository = new InMemoryStudentGuardianRepository();
|
||||
|
||||
$tenantId = TenantId::fromString(self::TENANT_ID);
|
||||
$now = new DateTimeImmutable('2026-02-10 10:00:00');
|
||||
|
||||
$this->studentUser = User::creer(
|
||||
email: new Email('student@example.com'),
|
||||
role: Role::ELEVE,
|
||||
tenantId: $tenantId,
|
||||
schoolName: 'École Test',
|
||||
dateNaissance: null,
|
||||
createdAt: $now,
|
||||
);
|
||||
|
||||
$userRepository = $this->createMock(UserRepository::class);
|
||||
$userRepository->method('get')->willReturn($this->studentUser);
|
||||
|
||||
$this->handler = new GetStudentsForParentHandler($this->repository, $userRepository);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function returnsEmptyWhenNoStudentsLinked(): void
|
||||
{
|
||||
$result = ($this->handler)(new GetStudentsForParentQuery(
|
||||
guardianId: self::GUARDIAN_ID,
|
||||
tenantId: self::TENANT_ID,
|
||||
));
|
||||
|
||||
self::assertSame([], $result);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function returnsStudentsForParent(): void
|
||||
{
|
||||
$this->repository->save(StudentGuardian::lier(
|
||||
studentId: UserId::fromString(self::STUDENT_1_ID),
|
||||
guardianId: UserId::fromString(self::GUARDIAN_ID),
|
||||
relationshipType: RelationshipType::FATHER,
|
||||
tenantId: TenantId::fromString(self::TENANT_ID),
|
||||
createdAt: new DateTimeImmutable(),
|
||||
));
|
||||
$this->repository->save(StudentGuardian::lier(
|
||||
studentId: UserId::fromString(self::STUDENT_2_ID),
|
||||
guardianId: UserId::fromString(self::GUARDIAN_ID),
|
||||
relationshipType: RelationshipType::FATHER,
|
||||
tenantId: TenantId::fromString(self::TENANT_ID),
|
||||
createdAt: new DateTimeImmutable(),
|
||||
));
|
||||
|
||||
$result = ($this->handler)(new GetStudentsForParentQuery(
|
||||
guardianId: self::GUARDIAN_ID,
|
||||
tenantId: self::TENANT_ID,
|
||||
));
|
||||
|
||||
self::assertCount(2, $result);
|
||||
self::assertContainsOnlyInstancesOf(StudentForParentDto::class, $result);
|
||||
self::assertSame(self::STUDENT_1_ID, $result[0]->studentId);
|
||||
self::assertSame(self::STUDENT_2_ID, $result[1]->studentId);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function dtoContainsCorrectData(): void
|
||||
{
|
||||
$this->repository->save(StudentGuardian::lier(
|
||||
studentId: UserId::fromString(self::STUDENT_1_ID),
|
||||
guardianId: UserId::fromString(self::GUARDIAN_ID),
|
||||
relationshipType: RelationshipType::MOTHER,
|
||||
tenantId: TenantId::fromString(self::TENANT_ID),
|
||||
createdAt: new DateTimeImmutable(),
|
||||
));
|
||||
|
||||
$result = ($this->handler)(new GetStudentsForParentQuery(
|
||||
guardianId: self::GUARDIAN_ID,
|
||||
tenantId: self::TENANT_ID,
|
||||
));
|
||||
|
||||
self::assertSame(RelationshipType::MOTHER->value, $result[0]->relationshipType);
|
||||
self::assertSame('Mère', $result[0]->relationshipLabel);
|
||||
self::assertSame($this->studentUser->firstName, $result[0]->firstName);
|
||||
self::assertSame($this->studentUser->lastName, $result[0]->lastName);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user