feat: additional functionality and layout adjustments for season teamers

This commit is contained in:
fromme committed 2026-09-26 12:13:16 +02:00
1 parent 80c6016da3
commit 4cab57d136
30 files changed
+916 -192

No files matched your search

@@ -0,0 +1,99 @@
<?php
declare(strict_types=1);
namespace App\Tests\Service\Season;
use App\Config\SeasonChecklistStatus;
use App\Config\SeasonTask;
use App\Entity\SeasonAssignment;
use App\Entity\SeasonAssignmentTask;
use App\Service\Season\SeasonChecklistBuilder;
use App\Service\Season\SeasonTaskDeadlineResolver;
use PHPUnit\Framework\TestCase;
/**
* The status the detail page shows instead of the removed done_teamer flag. It is derived, so
* the whole point is which combination of rows produces which stage - no database needed.
*/
class SeasonChecklistStatusTest extends TestCase
{
private SeasonChecklistBuilder $builder;
protected function setUp(): void
{
$this->builder = new SeasonChecklistBuilder($this->createMock(SeasonTaskDeadlineResolver::class));
}
public function testItIsOpenWhileAnEntryRequiringAReturnIsOpen(): void
{
$seasonAssignment = $this->assignmentWithAllTasks();
$this->assertSame(SeasonChecklistStatus::OPEN, $this->builder->status($seasonAssignment));
}
public function testItIsOpenWhenOnlyOfficeInternalEntriesAreDone(): void
{
$seasonAssignment = $this->assignmentWithAllTasks();
$this->markDone($seasonAssignment, static fn (SeasonTask $task): bool => false === $task->requiresReturn());
$this->assertSame(SeasonChecklistStatus::OPEN, $this->builder->status($seasonAssignment));
}
public function testReturnsAreCompleteWhileAnOfficeInternalEntryIsOpen(): void
{
$seasonAssignment = $this->assignmentWithAllTasks();
$this->markDone($seasonAssignment, static fn (SeasonTask $task): bool => $task->requiresReturn());
$this->assertSame(SeasonChecklistStatus::RETURNS_COMPLETE, $this->builder->status($seasonAssignment));
}
public function testItIsCompleteOnceEveryEntryIsDone(): void
{
$seasonAssignment = $this->assignmentWithAllTasks();
$this->markDone($seasonAssignment, static fn (SeasonTask $task): bool => true);
$this->assertSame(SeasonChecklistStatus::COMPLETE, $this->builder->status($seasonAssignment));
}
/**
* A row of an entry that was removed from the enum would otherwise keep the assignment
* unfinished forever, so it is skipped here just like everywhere else.
*/
public function testItIgnoresRowsWhoseEntryNoLongerExists(): void
{
$seasonAssignment = $this->assignmentWithAllTasks();
$this->markDone($seasonAssignment, static fn (SeasonTask $task): bool => true);
$seasonAssignment->addTask((new SeasonAssignmentTask())->setTaskKey('removed_entry'));
$this->assertSame(SeasonChecklistStatus::COMPLETE, $this->builder->status($seasonAssignment));
}
private function assignmentWithAllTasks(): SeasonAssignment
{
$seasonAssignment = new SeasonAssignment();
foreach (SeasonTask::cases() as $case) {
$seasonAssignment->addTask((new SeasonAssignmentTask())->setTaskKey($case->value));
}
return $seasonAssignment;
}
/**
* @param callable(SeasonTask): bool $matches
*/
private function markDone(SeasonAssignment $seasonAssignment, callable $matches): void
{
foreach ($seasonAssignment->getTasks() as $task) {
if (null !== $definition = $task->getTask()) {
$task->setDone($matches($definition));
}
}
}
}