buildPeriodWithId(1, '2026-01-01', null); $suspension = new ContractSuspension(); $suspension->setContractPeriod($period); $suspension->setStartDate(new DateTimeImmutable('2026-03-01')); $suspension->setEndDate(new DateTimeImmutable('2026-04-30')); $suspension->setComment('Congé sans solde'); $persistProcessor = $this->createMock(ProcessorInterface::class); $persistProcessor->expects(self::once())->method('process')->willReturn($suspension); $entityManager = $this->createStub(EntityManagerInterface::class); $processor = new ContractSuspensionWriteProcessor($persistProcessor, $entityManager); $result = $processor->process($suspension, new Post()); self::assertSame($suspension, $result); } public function testRejectsEndDateBeforeStartDate(): void { $period = $this->buildPeriodWithId(1, '2026-01-01', null); $suspension = new ContractSuspension(); $suspension->setContractPeriod($period); $suspension->setStartDate(new DateTimeImmutable('2026-05-01')); $suspension->setEndDate(new DateTimeImmutable('2026-03-01')); $persistProcessor = $this->createStub(ProcessorInterface::class); $entityManager = $this->createStub(EntityManagerInterface::class); $processor = new ContractSuspensionWriteProcessor($persistProcessor, $entityManager); $this->expectException(UnprocessableEntityHttpException::class); $processor->process($suspension, new Post()); } public function testRejectsStartDateBeforePeriodStart(): void { $period = $this->buildPeriodWithId(1, '2026-06-01', null); $suspension = new ContractSuspension(); $suspension->setContractPeriod($period); $suspension->setStartDate(new DateTimeImmutable('2026-01-01')); $persistProcessor = $this->createStub(ProcessorInterface::class); $entityManager = $this->createStub(EntityManagerInterface::class); $processor = new ContractSuspensionWriteProcessor($persistProcessor, $entityManager); $this->expectException(UnprocessableEntityHttpException::class); $processor->process($suspension, new Post()); } public function testRejectsOverlappingSuspension(): void { $period = $this->buildPeriodWithId(1, '2026-01-01', null); $existing = new ContractSuspension(); $existing->setContractPeriod($period); $existing->setStartDate(new DateTimeImmutable('2026-03-01')); $existing->setEndDate(new DateTimeImmutable('2026-04-30')); $period->getSuspensions()->add($existing); $suspension = new ContractSuspension(); $suspension->setContractPeriod($period); $suspension->setStartDate(new DateTimeImmutable('2026-04-01')); $suspension->setEndDate(new DateTimeImmutable('2026-05-31')); $persistProcessor = $this->createStub(ProcessorInterface::class); $entityManager = $this->createStub(EntityManagerInterface::class); $processor = new ContractSuspensionWriteProcessor($persistProcessor, $entityManager); $this->expectException(UnprocessableEntityHttpException::class); $processor->process($suspension, new Post()); } public function testRejectsClosedPeriod(): void { $period = $this->buildPeriodWithId(1, '2025-01-01', '2025-12-31'); $suspension = new ContractSuspension(); $suspension->setContractPeriod($period); $suspension->setStartDate(new DateTimeImmutable('2025-06-01')); $suspension->setEndDate(new DateTimeImmutable('2025-07-31')); $persistProcessor = $this->createStub(ProcessorInterface::class); $entityManager = $this->createStub(EntityManagerInterface::class); $processor = new ContractSuspensionWriteProcessor($persistProcessor, $entityManager); $this->expectException(UnprocessableEntityHttpException::class); $processor->process($suspension, new Post()); } private function buildPeriodWithId(int $id, string $start, ?string $end): EmployeeContractPeriod { $period = new EmployeeContractPeriod(); $period->setStartDate(new DateTimeImmutable($start)); if (null !== $end) { $period->setEndDate(new DateTimeImmutable($end)); } $period->setContractNature(ContractNature::CDI); $ref = new ReflectionProperty($period, 'id'); $ref->setValue($period, $id); return $period; } }