35 lines
1.5 KiB
PHP
35 lines
1.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_contract_assert(mixed $expected, mixed $actual, string $message): void
|
|
{
|
|
if ($expected !== $actual) {
|
|
throw new RuntimeException($message . "\nExpected: " . var_export($expected, true) . "\nActual: " . var_export($actual, true));
|
|
}
|
|
}
|
|
|
|
$record = new NotificationRecord();
|
|
$queue = new NotificationQueue($record);
|
|
|
|
$display = $record->toDisplay([
|
|
'type' => 'assignment_created',
|
|
'recipient' => 'tech@example.com',
|
|
'title' => '<script>alert(1)</script>',
|
|
'body' => '<b>unsafe</b>',
|
|
'deduplication_key' => 'assignment:42',
|
|
]);
|
|
notification_contract_assert('<script>alert(1)</script>', $display['title'], 'Safe display should preserve text as data, not execute or reinterpret it.');
|
|
notification_contract_assert('<b>unsafe</b>', $display['body'], 'Safe display should expose body as text data.');
|
|
notification_contract_assert(false, $display['is_read'], 'Display should default missing read_at to unread.');
|
|
|
|
notification_contract_assert(true, $record->validateMarkUnread(['notification_id' => '12'])['valid'], 'Unread command should accept a positive notification ID.');
|
|
notification_contract_assert(true, method_exists($queue, 'markUnread'), 'Queue should expose a mark-unread command.');
|
|
|
|
printf("Notification contract tests: 5 passed\n");
|