153 lines
6.3 KiB
PHP
153 lines
6.3 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\Entity\User;
|
|
use App\Enum\HalfDay;
|
|
use App\Repository\Contract\AbsenceReadRepositoryInterface;
|
|
use App\Repository\Contract\WorkHourReadRepositoryInterface;
|
|
use App\Service\PublicHolidayServiceInterface;
|
|
use App\State\AbsenceWriteProcessor;
|
|
use DateTime;
|
|
use Doctrine\ORM\EntityManagerInterface;
|
|
use PHPUnit\Framework\TestCase;
|
|
use Symfony\Bundle\SecurityBundle\Security;
|
|
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);
|
|
$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;
|
|
}
|
|
}
|