## Summary - implement Spec 192 across the targeted Filament record, detail, and edit pages with explicit action-surface inventory and guard coverage - add the focused Spec 192 browser smoke, feature tests, and spec artifacts under `specs/192-record-header-discipline` - improve unhandled promise rejection diagnostics by correlating 419s to the underlying Livewire request URL - disable panel-wide database notification polling on the admin, tenant, and system panels and cover the mitigation with focused tests ## Validation - `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament/DatabaseNotificationsPollingTest.php` - `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament/DatabaseNotificationsPollingTest.php tests/Feature/Filament/UnhandledRejectionLoggerAssetTest.php tests/Feature/Filament/FilamentNotificationsAssetsTest.php tests/Feature/Workspaces/ManagedTenantsLivewireUpdateTest.php tests/Feature/Filament/AdminSmokeTest.php` - `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent` - manual integrated-browser verification of the Spec 192 surfaces and the notification-polling mitigation ## Notes - Livewire v4 / Filament v5 compliance remains unchanged. - Provider registration stays in `bootstrap/providers.php`. - No Global Search behavior was expanded. - No destructive action confirmation semantics were relaxed. - The full test suite was not run in this PR. Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #226
40 lines
1.7 KiB
PHP
40 lines
1.7 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('window.fetch = async (...args) =>')
|
|
->toContain('XMLHttpRequest.prototype.open = function (method, url, ...rest)')
|
|
->toContain('const transport = resolveTransportMetadata(normalizedReason)')
|
|
->toContain('requestUrl: transport?.requestUrl ?? null')
|
|
->toContain('requestMethod: transport?.method ?? null')
|
|
->toContain('transportType: transport?.transportType ?? null')
|
|
->toContain('requestUrl: payload.requestUrl')
|
|
->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)');
|
|
});
|