feat: complete jobcard client management foundation
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
require_once __DIR__ . '/../app/Domain/User/RoleRecord.php';
|
||||
require_once __DIR__ . '/../app/Domain/User/PermissionMatrix.php';
|
||||
|
||||
use App\Domain\User\PermissionMatrix;
|
||||
use App\Domain\User\RoleRecord;
|
||||
|
||||
function role_permission_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));
|
||||
}
|
||||
}
|
||||
|
||||
function role_permission_assert_throws(callable $callback, string $message): void
|
||||
{
|
||||
try {
|
||||
$callback();
|
||||
} catch (LogicException) {
|
||||
return;
|
||||
}
|
||||
throw new RuntimeException($message);
|
||||
}
|
||||
|
||||
$roles = new RoleRecord();
|
||||
|
||||
role_permission_assert_same([
|
||||
'name' => 'Support Team',
|
||||
'description' => 'Handles customer support',
|
||||
], $roles->normalize([
|
||||
'name' => ' Support Team ',
|
||||
'description' => ' Handles customer support ',
|
||||
'permissions' => ['users.manage'],
|
||||
]), 'Role normalization should trim supported fields and ignore unrelated fields.');
|
||||
|
||||
$valid = $roles->validate(['name' => 'Support Team', 'description' => str_repeat('x', 255)]);
|
||||
role_permission_assert_same(true, $valid['valid'], 'A schema-sized custom role should validate.');
|
||||
role_permission_assert_same([], $valid['errors'], 'Valid role should have no errors.');
|
||||
|
||||
$invalid = $roles->validate(['name' => "\x01", 'description' => str_repeat('x', 256)]);
|
||||
role_permission_assert_same(false, $invalid['valid'], 'Invalid role data should report invalid.');
|
||||
if (!isset($invalid['errors']['name'], $invalid['errors']['description'])) {
|
||||
throw new RuntimeException('Role validation should report name and description errors.');
|
||||
}
|
||||
|
||||
role_permission_assert_throws(
|
||||
fn() => $roles->assertCanRename(['name' => 'Administrator'], 'Security Administrator'),
|
||||
'Administrator must not be renamed.'
|
||||
);
|
||||
role_permission_assert_throws(
|
||||
fn() => $roles->assertCanDelete(['name' => ' administrator ']),
|
||||
'Administrator must not be deleted.'
|
||||
);
|
||||
role_permission_assert_throws(
|
||||
fn() => $roles->assertCanChangePermissions(['name' => 'Administrator']),
|
||||
'Administrator permissions must not be changed.'
|
||||
);
|
||||
role_permission_assert_throws(
|
||||
fn() => $roles->assertCanRename(['name' => 'Accounts'], ' administrator '),
|
||||
'A custom role must not be renamed to Administrator.'
|
||||
);
|
||||
role_permission_assert_same(true, $roles->canRename(['name' => 'Accounts'], 'Support'), 'Custom roles should be renameable.');
|
||||
role_permission_assert_same(false, $roles->canDelete(['name' => 'Administrator']), 'Administrator deletion safeguard should be queryable.');
|
||||
|
||||
$display = $roles->display([
|
||||
'id' => 4,
|
||||
'name' => 'Support Team',
|
||||
'description' => 'Handles support',
|
||||
'created_at' => '2026-09-01 08:00:00',
|
||||
'permissions' => ['clients.view'],
|
||||
'password_hash' => 'secret',
|
||||
'internal_notes' => 'omit',
|
||||
]);
|
||||
role_permission_assert_same([
|
||||
'id' => 4,
|
||||
'name' => 'Support Team',
|
||||
'description' => 'Handles support',
|
||||
'created_at' => '2026-09-01 08:00:00',
|
||||
'permissions' => ['clients.view'],
|
||||
], $display, 'Role display projection must allow-list safe fields.');
|
||||
|
||||
$permissions = new PermissionMatrix();
|
||||
role_permission_assert_same([
|
||||
'clients.view',
|
||||
'jobcards.manage',
|
||||
'reports.view',
|
||||
], $permissions->normalize([
|
||||
' clients.view ',
|
||||
'jobcards.manage',
|
||||
'clients.view',
|
||||
'',
|
||||
'reports.view',
|
||||
' ',
|
||||
]), 'Permissions should be trimmed, blank entries removed, and duplicates de-duplicated.');
|
||||
|
||||
role_permission_assert_same([
|
||||
'clients.view',
|
||||
'jobcards.manage',
|
||||
], $permissions->normalize(['CLIENTS.VIEW', 'clients.view', ' jobcards.manage ']), 'Permission normalization should use canonical lower-case names.');
|
||||
|
||||
role_permission_assert_same([
|
||||
'id' => 4,
|
||||
'name' => 'Support Team',
|
||||
'permissions' => ['clients.view', 'jobcards.manage'],
|
||||
], $permissions->display([
|
||||
'id' => 4,
|
||||
'name' => 'Support Team',
|
||||
'permissions' => ['clients.view', 'jobcards.manage', 'clients.view'],
|
||||
'password' => 'secret',
|
||||
'token' => 'secret',
|
||||
]), 'Permission display projection must be safe and normalized.');
|
||||
|
||||
printf("Role and permission tests: 10 passed\n");
|
||||
Reference in New Issue
Block a user