repository = new InMemoryStudentGuardianRepository(); $this->tenantContext = new TenantContext(); $this->tenantContext->setCurrentTenant(new TenantConfig( tenantId: InfraTenantId::fromString(self::TENANT_ID), subdomain: self::SUBDOMAIN, databaseUrl: 'postgresql://test', )); } #[Test] public function returnsGuardiansForStudent(): void { $link = StudentGuardian::lier( studentId: UserId::fromString(self::STUDENT_ID), guardianId: UserId::fromString(self::GUARDIAN_ID), relationshipType: RelationshipType::FATHER, tenantId: TenantId::fromString(self::TENANT_ID), createdAt: new DateTimeImmutable('2026-02-10 10:00:00'), ); $this->repository->save($link); $provider = $this->createProvider(); $results = $provider->provide( new GetCollection(), ['studentId' => self::STUDENT_ID], ); self::assertCount(1, $results); self::assertInstanceOf(StudentGuardianResource::class, $results[0]); self::assertSame((string) $link->id, $results[0]->id); self::assertSame(self::GUARDIAN_ID, $results[0]->guardianId); self::assertSame('père', $results[0]->relationshipType); self::assertSame('Père', $results[0]->relationshipLabel); } #[Test] public function returnsEmptyArrayWhenNoGuardians(): void { $provider = $this->createProvider(); $results = $provider->provide( new GetCollection(), ['studentId' => self::STUDENT_ID], ); self::assertSame([], $results); } #[Test] public function throwsUnauthorizedWhenNoTenant(): void { $tenantContext = new TenantContext(); $provider = $this->createProvider(tenantContext: $tenantContext); $this->expectException(UnauthorizedHttpException::class); $provider->provide( new GetCollection(), ['studentId' => self::STUDENT_ID], ); } #[Test] public function throwsAccessDeniedWhenNotAuthorizedToViewStudent(): void { $authChecker = $this->createMock(AuthorizationCheckerInterface::class); $authChecker->method('isGranted') ->with(StudentGuardianVoter::VIEW_STUDENT, self::STUDENT_ID) ->willReturn(false); $provider = $this->createProvider(authorizationChecker: $authChecker); $this->expectException(AccessDeniedHttpException::class); $provider->provide( new GetCollection(), ['studentId' => self::STUDENT_ID], ); } private function createProvider( ?TenantContext $tenantContext = null, ?AuthorizationCheckerInterface $authorizationChecker = null, ): GuardiansForStudentProvider { $guardianUser = User::creer( email: new Email('guardian@example.com'), role: Role::PARENT, tenantId: TenantId::fromString(self::TENANT_ID), schoolName: 'École Test', dateNaissance: null, createdAt: new DateTimeImmutable('2026-02-10 10:00:00'), ); $userRepository = $this->createMock(UserRepository::class); $userRepository->method('get')->willReturn($guardianUser); $handler = new GetParentsForStudentHandler($this->repository, $userRepository); $tenantContext ??= $this->tenantContext; if ($authorizationChecker === null) { $authorizationChecker = $this->createMock(AuthorizationCheckerInterface::class); $authorizationChecker->method('isGranted') ->with(StudentGuardianVoter::VIEW_STUDENT, self::STUDENT_ID) ->willReturn(true); } return new GuardiansForStudentProvider( $handler, $tenantContext, $authorizationChecker, ); } }