34 lines
2.5 KiB
PHP
34 lines
2.5 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
require_once __DIR__ . '/../app/Domain/Jobcard/JobcardReference.php';
|
|
require_once __DIR__ . '/../app/Domain/Jobcard/StatusTransitionValidator.php';
|
|
require_once __DIR__ . '/../app/Domain/Jobcard/TimeEntryValidator.php';
|
|
require_once __DIR__ . '/../app/Domain/Jobcard/TimeAggregator.php';
|
|
|
|
use App\Domain\Jobcard\JobcardReference;
|
|
use App\Domain\Jobcard\StatusTransitionValidator;
|
|
use App\Domain\Jobcard\TimeEntryValidator;
|
|
use App\Domain\Jobcard\TimeAggregator;
|
|
|
|
$reference = JobcardReference::generate(42, 2026);
|
|
if ($reference !== 'JC-2026-000042') throw new RuntimeException('Expected generated jobcard reference.');
|
|
if (!JobcardReference::isValid($reference) || JobcardReference::isValid('bad-reference')) throw new RuntimeException('Expected reference format validation.');
|
|
|
|
$transitions = new StatusTransitionValidator();
|
|
if (!$transitions->canTransition('new', 'assigned')) throw new RuntimeException('new should transition to assigned.');
|
|
if ($transitions->canTransition('new', 'completed')) throw new RuntimeException('new should not skip to completed.');
|
|
if (!$transitions->canTransition('in_progress', 'in_progress')) throw new RuntimeException('Same status should be allowed.');
|
|
|
|
$validEntry = (new TimeEntryValidator())->validate(['work_date' => '2026-09-01', 'start_time' => '09:00', 'end_time' => '11:30']);
|
|
if (!$validEntry['valid'] || $validEntry['hours'] !== 2.5 || $validEntry['errors'] !== []) throw new RuntimeException('Expected valid time entry.');
|
|
$invalidEntry = (new TimeEntryValidator())->validate(['work_date' => 'not-a-date', 'start_time' => '11:00', 'end_time' => '10:00']);
|
|
if ($invalidEntry['valid'] || count($invalidEntry['errors']) !== 2) throw new RuntimeException('Expected invalid time entry errors.');
|
|
$nonNumericEntry = (new TimeEntryValidator())->validate(['work_date' => '2026-09-01', 'hours' => 'not-a-number']);
|
|
if ($nonNumericEntry['valid'] || !isset($nonNumericEntry['errors']['hours'])) throw new RuntimeException('Expected non-numeric hours to be rejected.');
|
|
|
|
$aggregator = new TimeAggregator();
|
|
if ($aggregator->total([['hours' => 2.25], ['hours' => 1.5], ['hours' => -4]]) !== 3.75) throw new RuntimeException('Expected positive time aggregation.');
|
|
if ($aggregator->slaTotal([['hours' => 2, 'counts_toward_sla' => true], ['hours' => 3, 'counts_toward_sla' => false], ['hours' => 1, 'counts_toward_sla' => 1]]) !== 3.0) throw new RuntimeException('Expected SLA-filtered aggregation.');
|
|
printf("Jobcard domain tests: 12 passed\n");
|