Files
JobcardSystem/tests/JobcardDomainTest.php
T

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");