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; } }