feat: list upcoming season assignments among a teamer's dispositions

This commit is contained in:
fromme committed 2026-10-20 17:13:45 +02:00
1 parent 300bb2058f
commit c00dd86eb4
17 files changed
+386 -97

No files matched your search

@@ -52,6 +52,25 @@ class SeasonAssignmentRepositoryTest extends KernelTestCase
);
}
/**
* 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 */
@@ -0,0 +1,79 @@
<?php
declare(strict_types=1);
namespace App\Tests\Service\Teamer;
use App\Entity\Application;
use App\Entity\Assignment;
use App\Entity\Destination;
use App\Entity\Disposition;
use App\Entity\SeasonAssignment;
use App\Entity\Teamer;
use App\Repository\DispositionRepository;
use App\Repository\SeasonAssignmentRepository;
use App\Service\Teamer\UpcomingPlacementCollector;
use PHPUnit\Framework\TestCase;
class UpcomingPlacementCollectorTest extends TestCase
{
public function testBothKindsAreMergedEarliestFirst(): void
{
$early = $this->disposition('2026-10-25', '2026-11-01');
$late = $this->disposition('2027-05-01', '2027-05-08');
$season = (new SeasonAssignment())
->setDateFrom(new \DateTimeImmutable('2026-11-01'))
->setDateTo(new \DateTimeImmutable('2027-04-30'));
$rows = $this->collector([$late, $early], [$season])->collect(new Teamer());
$this->assertSame([$early, null, $late], array_column($rows, 'disposition'));
$this->assertSame([null, $season, null], array_column($rows, 'seasonAssignment'));
$this->assertSame('2027-04-30', $rows[1]['dateTo']?->format('Y-m-d'));
}
/**
* The season frames the dispositions inside it, so on the same first day it comes first.
*/
public function testASeasonStartingOnTheSameDayComesBeforeTheDisposition(): void
{
$disposition = $this->disposition('2026-11-01', '2026-11-08');
$season = (new SeasonAssignment())
->setDateFrom(new \DateTimeImmutable('2026-11-01'))
->setDateTo(new \DateTimeImmutable('2027-04-30'));
$rows = $this->collector([$disposition], [$season])->collect(new Teamer());
$this->assertSame($season, $rows[0]['seasonAssignment']);
$this->assertSame($disposition, $rows[1]['disposition']);
}
public function testNothingUpcomingYieldsNoRows(): void
{
$this->assertSame([], $this->collector([], [])->collect(new Teamer()));
}
/**
* @param Disposition[] $dispositions
* @param SeasonAssignment[] $seasonAssignments
*/
private function collector(array $dispositions, array $seasonAssignments): UpcomingPlacementCollector
{
$dispositionRepository = $this->createStub(DispositionRepository::class);
$dispositionRepository->method('findAllUpcomingByTeamer')->willReturn($dispositions);
$seasonAssignmentRepository = $this->createStub(SeasonAssignmentRepository::class);
$seasonAssignmentRepository->method('findUpcomingByTeamer')->willReturn($seasonAssignments);
return new UpcomingPlacementCollector($dispositionRepository, $seasonAssignmentRepository);
}
private function disposition(string $dateFrom, string $dateTo): Disposition
{
$destination = (new Destination())
->setDateFrom(new \DateTimeImmutable($dateFrom))
->setDateTo(new \DateTimeImmutable($dateTo));
return new Disposition(new Application((new Assignment())->setDestination($destination), new Teamer()));
}
}