validator = new EmployeeContractPeriodValidator(); } public function testAssertPeriodDatesRejectsEndBeforeStart(): void { $this->expectException(UnprocessableEntityHttpException::class); $this->expectExceptionMessage('contractEndDate cannot be before contractStartDate.'); $this->validator->assertPeriodDates( new DateTimeImmutable('2026-03-10'), new DateTimeImmutable('2026-03-01'), ContractNature::CDD ); } public function testAssertPeriodDatesRejectsMissingEndDateForCdd(): void { $this->expectException(UnprocessableEntityHttpException::class); $this->expectExceptionMessage('contractEndDate is required for CDD and INTERIM.'); $this->validator->assertPeriodDates( new DateTimeImmutable('2026-03-01'), null, ContractNature::CDD ); } public function testAssertPeriodDatesRejectsEndDateForCdiWhenNotAllowed(): void { $this->expectException(UnprocessableEntityHttpException::class); $this->expectExceptionMessage('contractEndDate must be empty for CDI.'); $this->validator->assertPeriodDates( new DateTimeImmutable('2026-03-01'), new DateTimeImmutable('2026-03-10'), ContractNature::CDI ); } public function testAssertCloseEndDateCanBeAppliedRejectsIncrease(): void { $this->expectException(UnprocessableEntityHttpException::class); $this->expectExceptionMessage('contractEndDate cannot be increased on current contract.'); $this->validator->assertCloseEndDateCanBeApplied( new DateTimeImmutable('2026-03-01'), new DateTimeImmutable('2026-03-10'), new DateTimeImmutable('2026-03-11'), ContractNature::CDI ); } public function testAssertNextStartDateCompatibleRejectsWhenNotAfterCurrentOpenStart(): void { $currentPeriod = $this->buildCurrentPeriod('2026-03-05', null); $this->expectException(UnprocessableEntityHttpException::class); $this->expectExceptionMessage('contractStartDate must be after current contract start date.'); $this->validator->assertNextStartDateCompatible(new DateTimeImmutable('2026-03-05'), $currentPeriod); } public function testAssertNextStartDateCompatibleRejectsWhenNotAfterCurrentClosedEnd(): void { $currentPeriod = $this->buildCurrentPeriod('2026-03-01', '2026-03-10'); $this->expectException(UnprocessableEntityHttpException::class); $this->expectExceptionMessage('contractStartDate must be after current contract end date.'); $this->validator->assertNextStartDateCompatible(new DateTimeImmutable('2026-03-10'), $currentPeriod); } private function buildCurrentPeriod(string $startDate, ?string $endDate): EmployeeContractPeriod { $contract = new Contract() ->setName('35h') ->setTrackingMode(Contract::TRACKING_TIME) ->setWeeklyHours(35) ; $employee = new Employee() ->setFirstName('Test') ->setLastName('User') ->setContract($contract) ; return new EmployeeContractPeriod() ->setEmployee($employee) ->setContract($contract) ->setStartDate(new DateTimeImmutable($startDate)) ->setEndDate(null !== $endDate ? new DateTimeImmutable($endDate) : null) ->setContractNature(ContractNature::CDI) ; } }