97 lines
3.5 KiB
PHP
97 lines
3.5 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Tests\Repository;
|
|
|
|
use App\Entity\TeamerWorkMonth;
|
|
use App\Enum\WorkMonthStatus;
|
|
use App\Model\WorkMonthFilterDto;
|
|
use App\Repository\TeamerWorkMonthRepository;
|
|
use Doctrine\ORM\EntityManagerInterface;
|
|
use Doctrine\ORM\Query;
|
|
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
|
|
|
/**
|
|
* The list's defaults are the part worth pinning: what an admin sees when they have chosen
|
|
* no filter at all is decided in DQL, not in the template.
|
|
*/
|
|
class TeamerWorkMonthRepositoryTest extends KernelTestCase
|
|
{
|
|
public function testTheListHidesApprovedMonthsUntilAskedFor(): void
|
|
{
|
|
$query = $this->createListQuery(new WorkMonthFilterDto());
|
|
|
|
$this->assertStringContainsString('work_month.status != :approved', $query->getDQL());
|
|
$this->assertSame(WorkMonthStatus::APPROVED, $query->getParameter('approved')->getValue());
|
|
}
|
|
|
|
public function testApprovedMonthsComeBackWhenTheFlagIsSet(): void
|
|
{
|
|
$query = $this->createListQuery((new WorkMonthFilterDto())->setIncludeApproved(true));
|
|
|
|
$this->assertStringNotContainsString(':approved', $query->getDQL());
|
|
}
|
|
|
|
/**
|
|
* An explicit status choice has to win over the "hide approved" default, or picking
|
|
* "Geprüft" from the filter would return nothing at all.
|
|
*/
|
|
public function testAnExplicitStatusChoiceOverridesTheDefault(): void
|
|
{
|
|
$query = $this->createListQuery(
|
|
(new WorkMonthFilterDto())->setStatuses([WorkMonthStatus::APPROVED])
|
|
);
|
|
|
|
$dql = $query->getDQL();
|
|
|
|
$this->assertStringContainsString('work_month.status IN (:statuses)', $dql);
|
|
$this->assertStringNotContainsString(':approved', $dql);
|
|
$this->assertSame([WorkMonthStatus::APPROVED], $query->getParameter('statuses')->getValue());
|
|
}
|
|
|
|
public function testFilteringByMonthSplitsThePeriodIntoItsColumns(): void
|
|
{
|
|
$query = $this->createListQuery(
|
|
(new WorkMonthFilterDto())->setPeriod(new \DateTimeImmutable('2026-03-01'))
|
|
);
|
|
|
|
$this->assertStringContainsString('work_month.year = :year', $query->getDQL());
|
|
$this->assertStringContainsString('work_month.month = :month', $query->getDQL());
|
|
$this->assertSame(2026, $query->getParameter('year')->getValue());
|
|
$this->assertSame(3, $query->getParameter('month')->getValue(), 'The calendar month, not the API index.');
|
|
}
|
|
|
|
/**
|
|
* The reminder must not chase someone who has already sent the sheet in, nor a deleted
|
|
* teamer.
|
|
*/
|
|
public function testTheReminderQueryOnlyLooksAtMonthsStillWaiting(): void
|
|
{
|
|
$repository = $this->createRepository();
|
|
$months = $repository->findAwaitingDocument(new \DateTimeImmutable('2026-03-04'));
|
|
|
|
// db_test starts empty, so this asserts the query runs at all - the semantics above
|
|
// are what the DQL assertions cover.
|
|
$this->assertSame([], $months);
|
|
}
|
|
|
|
private function createListQuery(WorkMonthFilterDto $filterDto): Query
|
|
{
|
|
return $this->createRepository()->getListQuery($filterDto);
|
|
}
|
|
|
|
private function createRepository(): TeamerWorkMonthRepository
|
|
{
|
|
self::bootKernel();
|
|
|
|
/** @var EntityManagerInterface $entityManager */
|
|
$entityManager = self::getContainer()->get(EntityManagerInterface::class);
|
|
|
|
/** @var TeamerWorkMonthRepository $repository */
|
|
$repository = $entityManager->getRepository(TeamerWorkMonth::class);
|
|
|
|
return $repository;
|
|
}
|
|
}
|