createMock(EntityManagerInterface::class); $absenceRepository = $this->createMock(AbsenceReadRepositoryInterface::class); $workHourRepository = $this->createMock(WorkHourReadRepositoryInterface::class); $security = $this->createAdminSecurityStub(); $this->processor = new AbsenceWriteProcessor($entityManager, $absenceRepository, $workHourRepository, $security, $this->createEmptyHolidayServiceStub()); $absence = $this->buildAbsence('2026-02-16', '2026-02-18', HalfDay::AM, HalfDay::PM); $workHourRepository->expects(self::once()) ->method('hasValidatedInRange') ->willReturn(false) ; $absenceRepository->expects(self::once()) ->method('findByEmployeeAndDateRange') ->willReturn([]) ; $entityManager->expects(self::exactly(3))->method('persist'); $entityManager->expects(self::once())->method('flush'); $result = $this->processor->process($absence, new Post()); self::assertSame($absence, $result); self::assertSame('2026-02-16', $absence->getStartDate()->format('Y-m-d')); self::assertSame('2026-02-16', $absence->getEndDate()->format('Y-m-d')); } public function testDeleteThrowsWhenValidated(): void { $entityManager = $this->createMock(EntityManagerInterface::class); $absenceRepository = $this->createStub(AbsenceReadRepositoryInterface::class); $workHourRepository = $this->createMock(WorkHourReadRepositoryInterface::class); $security = $this->createAdminSecurityStub(); $this->processor = new AbsenceWriteProcessor($entityManager, $absenceRepository, $workHourRepository, $security, $this->createEmptyHolidayServiceStub()); $absence = $this->buildAbsence('2026-02-16', '2026-02-16', HalfDay::AM, HalfDay::PM); $workHourRepository->expects(self::once()) ->method('hasValidatedInRange') ->willReturn(true) ; $entityManager->expects(self::never())->method('remove'); $entityManager->expects(self::never())->method('flush'); $this->expectException(ConflictHttpException::class); $this->processor->process($absence, new Delete()); } public function testDeleteRemovesWhenNotValidated(): void { $entityManager = $this->createMock(EntityManagerInterface::class); $absenceRepository = $this->createStub(AbsenceReadRepositoryInterface::class); $workHourRepository = $this->createMock(WorkHourReadRepositoryInterface::class); $security = $this->createAdminSecurityStub(); $this->processor = new AbsenceWriteProcessor($entityManager, $absenceRepository, $workHourRepository, $security, $this->createEmptyHolidayServiceStub()); $absence = $this->buildAbsence('2026-02-16', '2026-02-16', HalfDay::AM, HalfDay::PM); $workHourRepository->expects(self::once()) ->method('hasValidatedInRange') ->willReturn(false) ; $entityManager->expects(self::once())->method('remove')->with($absence); $entityManager->expects(self::once())->method('flush'); $result = $this->processor->process($absence, new Delete()); self::assertNull($result); } public function testPostThrowsOnInvalidHalfDayOrder(): void { $entityManager = $this->createStub(EntityManagerInterface::class); $absenceRepository = $this->createStub(AbsenceReadRepositoryInterface::class); $workHourRepository = $this->createStub(WorkHourReadRepositoryInterface::class); $security = $this->createAdminSecurityStub(); $this->processor = new AbsenceWriteProcessor($entityManager, $absenceRepository, $workHourRepository, $security, $this->createEmptyHolidayServiceStub()); $absence = $this->buildAbsence('2026-02-16', '2026-02-16', HalfDay::PM, HalfDay::AM); $this->expectException(UnprocessableEntityHttpException::class); $this->processor->process($absence, new Post()); } private function buildAbsence(string $startDate, string $endDate, HalfDay $startHalf, HalfDay $endHalf): Absence { $contract = new Contract()->setName('35h')->setTrackingMode(Contract::TRACKING_TIME)->setWeeklyHours(35); $employee = new Employee()->setFirstName('Test')->setLastName('User')->setContract($contract); $type = new AbsenceType()->setCode('CP')->setLabel('Congé')->setColor('#000')->setCountAsWorkedHours(true); return new Absence() ->setEmployee($employee) ->setType($type) ->setComment('x') ->setStartDate(new DateTime($startDate)) ->setEndDate(new DateTime($endDate)) ->setStartHalf($startHalf) ->setEndHalf($endHalf) ; } private function createAdminSecurityStub(): Security { $security = $this->createStub(Security::class); $security->method('getUser')->willReturn( new User()->setUsername('admin')->setRoles(['ROLE_ADMIN']) ); return $security; } private function createEmptyHolidayServiceStub(): PublicHolidayServiceInterface { $service = $this->createStub(PublicHolidayServiceInterface::class); $service->method('getHolidaysDayByYears')->willReturn([]); return $service; } }