Files
SIRH/tests/State/AbsenceWriteProcessorTest.php
2026-02-19 22:06:54 +01:00

127 lines
5.2 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Tests\State;
use ApiPlatform\Metadata\Delete;
use ApiPlatform\Metadata\Post;
use App\Entity\Absence;
use App\Entity\AbsenceType;
use App\Entity\Contract;
use App\Entity\Employee;
use App\Enum\HalfDay;
use App\Repository\Contract\AbsenceReadRepositoryInterface;
use App\Repository\Contract\WorkHourReadRepositoryInterface;
use App\State\AbsenceWriteProcessor;
use DateTime;
use Doctrine\ORM\EntityManagerInterface;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpKernel\Exception\ConflictHttpException;
use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException;
/**
* @internal
*/
final class AbsenceWriteProcessorTest extends TestCase
{
private AbsenceWriteProcessor $processor;
public function testPostSplitsRangeIntoDailyEntries(): void
{
$entityManager = $this->createMock(EntityManagerInterface::class);
$absenceRepository = $this->createMock(AbsenceReadRepositoryInterface::class);
$workHourRepository = $this->createMock(WorkHourReadRepositoryInterface::class);
$this->processor = new AbsenceWriteProcessor($entityManager, $absenceRepository, $workHourRepository);
$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);
$this->processor = new AbsenceWriteProcessor($entityManager, $absenceRepository, $workHourRepository);
$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);
$this->processor = new AbsenceWriteProcessor($entityManager, $absenceRepository, $workHourRepository);
$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);
$this->processor = new AbsenceWriteProcessor($entityManager, $absenceRepository, $workHourRepository);
$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);
}
}