## Summary - add tenant triage review-state persistence, fingerprinting, resolver logic, service layer, and migration for current affected-set tracking - surface review-state and affected-set progress across tenant registry, tenant dashboard arrival continuity, and workspace overview - extend RBAC, audit/badge support, specs, and test coverage for portfolio triage review-state workflows - suppress expected hidden-page background transport failures in the global unhandled rejection logger while keeping visible-page failures logged ## Validation - targeted Pest coverage added for tenant registry, workspace overview, arrival context, RBAC authorization, badges, fingerprinting, resolver behavior, and logger asset behavior - code formatted with `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent` ## Notes - full suite was not re-run in this final step - branch includes the spec artifacts under `specs/189-portfolio-triage-review-state/` Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #220
33 lines
1.2 KiB
PHP
33 lines
1.2 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
it('injects the unhandled rejection logger into Filament pages', function (): void {
|
|
$this->get('/admin/login')
|
|
->assertSuccessful()
|
|
->assertSee('js/tenantpilot/unhandled-rejection-logger.js', escape: false);
|
|
});
|
|
|
|
it('ships a window unhandledrejection logger with structured payload output', function (): void {
|
|
$js = file_get_contents(public_path('js/tenantpilot/unhandled-rejection-logger.js'));
|
|
|
|
expect($js)->toBeString();
|
|
expect($js)
|
|
->toContain('__tenantpilotUnhandledRejectionLoggerApplied')
|
|
->toContain("window.addEventListener('unhandledrejection'")
|
|
->toContain('isExpectedBackgroundTransportFailure')
|
|
->toContain("document.visibilityState !== 'visible'")
|
|
->toContain('document.hasFocus')
|
|
->toContain('event.preventDefault()')
|
|
->toContain('status === 419')
|
|
->toContain('Page Expired')
|
|
->toContain('status === 404')
|
|
->toContain('Not Found')
|
|
->toContain('const dedupeKey = toStableJson({')
|
|
->toContain('reason: payload.reason')
|
|
->toContain('TenantPilot unhandled promise rejection')
|
|
->toContain('JSON.stringify')
|
|
->not->toContain('recentKeys.has(payloadJson)')
|
|
->not->toContain('recentKeys.set(payloadJson, nowMs)');
|
|
});
|