createMock(MailerInterface::class); $twig = $this->createMock(Environment::class); $userRepository = $this->createMock(UserRepository::class); $twig->method('render')->willReturn('notification'); $userRepository->method('findAllByTenant')->willReturn([ $this->createUser('teacher1@school.fr', [Role::PROF]), $this->createUser('teacher2@school.fr', [Role::PROF]), $this->createUser('parent@school.fr', [Role::PARENT]), ]); $mailer->expects(self::exactly(2))->method('send'); $handler = new NotifyTeachersPedagogicalDayHandler($mailer, $twig, $userRepository, new NullLogger()); ($handler)($this->createEvent()); } #[Test] public function itSkipsWhenNoTeachersInTenant(): void { $mailer = $this->createMock(MailerInterface::class); $twig = $this->createMock(Environment::class); $userRepository = $this->createMock(UserRepository::class); $userRepository->method('findAllByTenant')->willReturn([ $this->createUser('parent@school.fr', [Role::PARENT]), ]); $mailer->expects(self::never())->method('send'); $twig->expects(self::never())->method('render'); $handler = new NotifyTeachersPedagogicalDayHandler($mailer, $twig, $userRepository, new NullLogger()); ($handler)($this->createEvent()); } #[Test] public function itHandlesMailerFailureGracefully(): void { $mailer = $this->createMock(MailerInterface::class); $twig = $this->createMock(Environment::class); $userRepository = $this->createMock(UserRepository::class); $twig->method('render')->willReturn('notification'); $userRepository->method('findAllByTenant')->willReturn([ $this->createUser('teacher@school.fr', [Role::PROF]), ]); $mailer->method('send')->willThrowException(new RuntimeException('SMTP error')); $handler = new NotifyTeachersPedagogicalDayHandler($mailer, $twig, $userRepository, new NullLogger()); ($handler)($this->createEvent()); $this->addToAssertionCount(1); } private function createEvent(): JourneePedagogiqueAjoutee { return new JourneePedagogiqueAjoutee( entryId: CalendarEntryId::generate(), tenantId: TenantId::fromString(self::TENANT_ID), academicYearId: AcademicYearId::fromString(self::ACADEMIC_YEAR_ID), date: new DateTimeImmutable('2025-03-14'), label: 'Formation enseignants', occurredOn: new DateTimeImmutable('2026-02-18 10:00:00'), ); } /** * @param Role[] $roles */ private function createUser(string $email, array $roles): User { return User::reconstitute( id: UserId::generate(), email: new Email($email), roles: $roles, tenantId: TenantId::fromString(self::TENANT_ID), schoolName: 'École Test', statut: StatutCompte::ACTIF, dateNaissance: null, createdAt: new DateTimeImmutable('2026-01-01'), hashedPassword: 'hashed', activatedAt: new DateTimeImmutable('2026-01-02'), consentementParental: null, ); } }