45 lines
3.5 KiB
PHP
45 lines
3.5 KiB
PHP
<?php
|
|||
|
|
declare(strict_types=1);
|
||
|
|
|
||
|
|
require_once __DIR__ . '/../app/Domain/Notification/NotificationRecord.php';
|
||
|
|
require_once __DIR__ . '/../app/Domain/Notification/NotificationQueue.php';
|
||
|
|
|
||
|
|
use App\Domain\Notification\NotificationRecord;
|
||
|
|
use App\Domain\Notification\NotificationQueue;
|
||
|
|
|
||
|
|
function notification_assert_same(mixed $expected, mixed $actual, string $message): void
|
||
|
|
{
|
||
|
|
if ($expected !== $actual) {
|
||
|
|
throw new RuntimeException($message . "\nExpected: " . var_export($expected, true) . "\nActual: " . var_export($actual, true));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
$records = new NotificationRecord();
|
||
|
|
notification_assert_same(false, $records->normalize(['type' => 'assignment_created', 'recipient' => 'A@EXAMPLE.COM', 'read' => 'unread', 'dedup_key' => ' Assignment:7 '])['is_read'], 'Unread aliases should normalize to false.');
|
||
|
|
notification_assert_same(true, $records->normalize(['type' => 'assignment_created', 'recipient' => 'a@example.com', 'read' => 'read', 'dedup_key' => 'assignment:7'])['is_read'], 'Read aliases should normalize to true.');
|
||
|
|
notification_assert_same(true, $records->validateMarkRead(['notification_id' => '12'])['valid'], 'A positive notification ID should be accepted for marking read.');
|
||
|
|
notification_assert_same(12, $records->validateMarkRead(['id' => '12'])['notification_id'], 'Mark-read IDs should normalize to integers.');
|
||
|
|
notification_assert_same(false, $records->validateMarkRead(['notification_id' => '0'])['valid'], 'Zero is not a valid notification ID.');
|
||
|
|
|
||
|
|
$assignment = $records->assignmentCreated([
|
||
|
|
'jobcard_id' => '42', 'jobcard_reference' => 'JC-2026-000042',
|
||
|
|
'recipients' => ['Tech@Example.com'], 'technician_name' => ' Sam ',
|
||
|
|
]);
|
||
|
|
notification_assert_same('assignment_created', $assignment['type'], 'Assignment factory should set its event type.');
|
||
|
|
notification_assert_same('assignment:42', $assignment['deduplication_key'], 'Assignment factory should use a stable deduplication key.');
|
||
|
|
notification_assert_same(['tech@example.com'], $assignment['recipients'], 'Factories should normalize recipients.');
|
||
|
|
|
||
|
|
$status = $records->statusChanged(['jobcard_id' => 42, 'from_status' => 'new', 'to_status' => 'assigned', 'recipients' => ['ops@example.com']]);
|
||
|
|
notification_assert_same('jobcard_status_changed', $status['type'], 'Status factory should set its event type.');
|
||
|
|
notification_assert_same('jobcard:42:status:assigned', $status['deduplication_key'], 'Status factory should key by jobcard and destination status.');
|
||
|
|
|
||
|
|
$sla = $records->slaThreshold(['client_id' => 9, 'threshold' => 'critical', 'used_hours' => 9, 'allocated_hours' => 10, 'recipients' => ['ops@example.com']]);
|
||
|
|
notification_assert_same('sla_threshold', $sla['type'], 'SLA factory should set its event type.');
|
||
|
|
notification_assert_same('sla:9:critical', $sla['deduplication_key'], 'SLA factory should key by client and threshold.');
|
||
|
|
|
||
|
|
$mapped = (new NotificationQueue())->mapForUser(['type' => 'assignment_created', 'recipients' => ['a@example.com', 'b@example.com'], 'title' => 'Assigned', 'deduplication_key' => 'assignment:42'], 'b@example.com');
|
||
|
|
notification_assert_same(['type' => 'assignment_created', 'recipient' => 'b@example.com', 'title' => 'Assigned', 'body' => null, 'is_read' => false, 'deduplication_key' => 'assignment:42'], $mapped, 'Queue mapping should produce one per-user DTO.');
|
||
|
|
notification_assert_same(2, count($records->toQueueDtos(['type' => 'assignment_created', 'recipients' => ['a@example.com', 'b@example.com'], 'title' => 'Assigned', 'deduplication_key' => 'assignment:42'])), 'Queue DTO mapping should produce one DTO per recipient.');
|
||
|
|
|
||
|
|
printf("Notification domain tests: 11 passed\n");
|