Files
myep-team/tests/Repository/SeasonAssignmentRepositoryTest.php
T

90 lines
3.5 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Tests\Repository;
use App\Entity\SeasonAssignment;
use App\Entity\Teamer;
use App\Repository\SeasonAssignmentRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
/**
* The rule that a teamer gets one season assignment per season is only as good as the window the
* query asks for, so the conditions are compiled and pinned here - the suite has no fixtures.
*/
class SeasonAssignmentRepositoryTest extends KernelTestCase
{
public function testTheSeasonWindowQueryBucketsByTheAssignmentsFirstDay(): void
{
$dql = $this->createInSeasonWindowQueryBuilder()->getQuery()->getDQL();
// both bounds on dateFrom: a placement running past the last day of the season still
// belongs to that season, so dateTo must not be part of the test
$this->assertStringContainsString('season_assignment.dateFrom >= :windowStart', $dql);
$this->assertStringContainsString('season_assignment.dateFrom <= :windowEnd', $dql);
$this->assertStringNotContainsString('dateTo', $dql);
}
/**
* The period is the assignment's own, so there is no second row left to join - and none that
* could be soft-deleted underneath a live placement.
*/
public function testTheSeasonWindowQueryNeedsNoJoin(): void
{
$dql = $this->createInSeasonWindowQueryBuilder()->getQuery()->getDQL();
$this->assertStringContainsString('season_assignment.deletedAt IS NULL', $dql);
$this->assertStringNotContainsString('destination', $dql);
}
public function testTheSeasonWindowQueryOnlyExcludesARowWhenEditingOne(): void
{
$this->assertStringNotContainsString(
'season_assignment.id <> :excludeId',
$this->createInSeasonWindowQueryBuilder()->getQuery()->getDQL()
);
$this->assertStringContainsString(
'season_assignment.id <> :excludeId',
$this->createInSeasonWindowQueryBuilder(42)->getQuery()->getDQL()
);
}
/**
* Upcoming means "not ended yet", like the dispositions it is listed with - a running season
* is still shown - and a deleted placement is not.
*/
public function testTheUpcomingQueryKeepsRunningAssignmentsAndDropsDeletedOnes(): void
{
/** @var EntityManagerInterface $entityManager */
$entityManager = static::getContainer()->get(EntityManagerInterface::class);
/** @var SeasonAssignmentRepository $repository */
$repository = $entityManager->getRepository(SeasonAssignment::class);
$dql = $repository->createUpcomingByTeamerQueryBuilder(new Teamer())->getQuery()->getDQL();
$this->assertStringContainsString('season_assignment.dateTo >= :today', $dql);
$this->assertStringContainsString('season_assignment.deletedAt IS NULL', $dql);
$this->assertStringNotContainsString('season_assignment.dateFrom >=', $dql);
}
private function createInSeasonWindowQueryBuilder(?int $excludeId = null): \Doctrine\ORM\QueryBuilder
{
/** @var EntityManagerInterface $entityManager */
$entityManager = static::getContainer()->get(EntityManagerInterface::class);
/** @var SeasonAssignmentRepository $repository */
$repository = $entityManager->getRepository(SeasonAssignment::class);
return $repository->createInSeasonWindowQueryBuilder(
new Teamer(),
new \DateTimeImmutable('2026-11-01'),
new \DateTimeImmutable('2027-04-01'),
$excludeId
);
}
}