feat: bootstrap JOBcard CRM foundation
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
require_once __DIR__ . '/../app/Domain/Reporting/ReportDataMapper.php';
|
||||
require_once __DIR__ . '/../app/Domain/Reporting/HoursPerClientReport.php';
|
||||
require_once __DIR__ . '/../app/Domain/Reporting/SlaReport.php';
|
||||
|
||||
function reporting_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));
|
||||
}
|
||||
}
|
||||
|
||||
$record = [
|
||||
'id' => 7,
|
||||
'name' => 'Acme IT',
|
||||
'status' => 'active',
|
||||
'support_email' => 'support@example.test',
|
||||
'internal_notes' => 'never disclose',
|
||||
'password' => 'secret',
|
||||
'credentials' => 'token',
|
||||
'technical_ip' => '10.0.0.1',
|
||||
'unknown_field' => 'not approved',
|
||||
];
|
||||
$mapper = new ReportDataMapper();
|
||||
reporting_assert_same(
|
||||
['id' => 7, 'name' => 'Acme IT', 'status' => 'active', 'support_email' => 'support@example.test'],
|
||||
$mapper->clientFacing($record),
|
||||
'Client-facing report data must be allow-listed.'
|
||||
);
|
||||
reporting_assert_same(
|
||||
['internal_notes' => 'never disclose', 'password' => 'secret', 'credentials' => 'token', 'technical_ip' => '10.0.0.1', 'unknown_field' => 'not approved'],
|
||||
$mapper->internal($record),
|
||||
'Internal report data must remain separate from client-facing data.'
|
||||
);
|
||||
|
||||
$hours = new HoursPerClientReport();
|
||||
reporting_assert_same(
|
||||
[
|
||||
['client_id' => 7, 'client_name' => 'Acme IT', 'hours' => 3.0],
|
||||
['client_id' => 2, 'client_name' => 'Beta', 'hours' => 3.5],
|
||||
],
|
||||
$hours->aggregate([
|
||||
['client_id' => 7, 'client_name' => 'Acme IT', 'hours' => 1.25],
|
||||
['client_id' => 2, 'client_name' => 'Beta', 'hours' => 3.5, 'internal_notes' => 'omit'],
|
||||
['client_id' => 7, 'client_name' => 'Acme IT', 'hours' => 1.75, 'password' => 'omit'],
|
||||
]),
|
||||
'Hours must aggregate deterministically per client.'
|
||||
);
|
||||
|
||||
$sla = new SlaReport();
|
||||
reporting_assert_same(
|
||||
[
|
||||
['client_id' => 7, 'client_name' => 'Acme IT', 'allocated_hours' => 10.0, 'used_hours' => 9.0, 'remaining_hours' => 1.0, 'usage_percentage' => 90.0, 'status' => 'critical'],
|
||||
],
|
||||
$sla->rows([[
|
||||
'client_id' => 7,
|
||||
'client_name' => 'Acme IT',
|
||||
'allocated_hours' => 10,
|
||||
'hours' => [4, 5, -2],
|
||||
'internal_notes' => 'omit',
|
||||
'credentials' => 'omit',
|
||||
]]),
|
||||
'SLA rows must expose only safe, deterministic report fields.'
|
||||
);
|
||||
|
||||
printf("Reporting contract tests: 3 passed\n");
|
||||
Reference in New Issue
Block a user