100 lines
3.3 KiB
PHP
100 lines
3.3 KiB
PHP
<?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));
|
|
}
|
|
}
|
|
}
|
|
}
|