## Summary - standardize Filament table defaults across resources, relation managers, widgets, custom pages, and picker tables - add shared pagination profiles, calm default column visibility, explicit empty states, and session persistence on designated critical resource lists - complete Spec 125 artifacts, regression tests, and dashboard widget follow-up for lazy loading, sortable columns, and toggleable detail columns ## Verification - `docker exec tenantatlas-laravel.test-1 php artisan test --compact --filter=BaselineCompareNow` - `docker exec tenantatlas-laravel.test-1 php artisan test --compact --filter=TableStandardsBaseline` - `docker exec tenantatlas-laravel.test-1 php artisan test --compact --filter=TableDetailVisibility` - `docker exec tenantatlas-laravel.test-1 php artisan test --compact --filter=FilamentTableRiskExceptions` - full suite run completed: `2017 passed, 10 failed, 8 skipped` - manual browser QA completed on the tenant dashboard for lazy loading, sortable widget columns, toggleable hidden status columns, badges, and pagination ## Known Failures The full suite still has 10 pre-existing failures unrelated to this branch: - `Tests\\Unit\\OpsUx\\SummaryCountsNormalizerTest` - `Tests\\Feature\\BackupWithAssignmentsConsistencyTest` (2 tests) - `Tests\\Feature\\BaselineDriftEngine\\CaptureBaselineContentTest` - `Tests\\Feature\\BaselineDriftEngine\\CompareContentEvidenceTest` - `Tests\\Feature\\BaselineDriftEngine\\ResolverTest` - `Tests\\Feature\\Filament\\TenantDashboardDbOnlyTest` - `Tests\\Feature\\Operations\\ReconcileAdapterRunsJobTrackingTest` - `Tests\\Feature\\ReviewPack\\ReviewPackRbacTest` - `Tests\\Feature\\Verification\\VerificationReportRedactionTest` Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #152
205 lines
11 KiB
PHP
205 lines
11 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use Illuminate\Support\Collection;
|
|
|
|
it('declares default sorts for the standardized table surface inventory', function (): void {
|
|
$paths = collect([
|
|
'app/Filament/Resources/TenantResource.php',
|
|
'app/Filament/Resources/PolicyResource.php',
|
|
'app/Filament/Resources/BackupSetResource.php',
|
|
'app/Filament/Resources/BackupScheduleResource.php',
|
|
'app/Filament/Resources/ProviderConnectionResource.php',
|
|
'app/Filament/Resources/FindingResource.php',
|
|
'app/Filament/Resources/OperationRunResource.php',
|
|
'app/Filament/Resources/EntraGroupResource.php',
|
|
'app/Filament/Resources/AlertDeliveryResource.php',
|
|
'app/Filament/Resources/AlertRuleResource.php',
|
|
'app/Filament/Resources/AlertDestinationResource.php',
|
|
'app/Filament/Resources/BaselineProfileResource.php',
|
|
'app/Filament/Resources/BaselineSnapshotResource.php',
|
|
'app/Filament/Resources/InventoryItemResource.php',
|
|
'app/Filament/Resources/PolicyVersionResource.php',
|
|
'app/Filament/Resources/ReviewPackResource.php',
|
|
'app/Filament/Resources/Workspaces/WorkspaceResource.php',
|
|
'app/Filament/Resources/TenantResource/RelationManagers/TenantMembershipsRelationManager.php',
|
|
'app/Filament/Resources/Workspaces/RelationManagers/WorkspaceMembershipsRelationManager.php',
|
|
'app/Filament/Resources/BaselineProfileResource/RelationManagers/BaselineTenantAssignmentsRelationManager.php',
|
|
'app/Filament/Resources/BackupSetResource/RelationManagers/BackupItemsRelationManager.php',
|
|
'app/Filament/Resources/PolicyResource/RelationManagers/VersionsRelationManager.php',
|
|
'app/Filament/Resources/BackupScheduleResource/RelationManagers/BackupScheduleOperationRunsRelationManager.php',
|
|
'app/Filament/Pages/InventoryCoverage.php',
|
|
'app/Filament/System/Pages/Directory/Tenants.php',
|
|
'app/Filament/System/Pages/Directory/Workspaces.php',
|
|
'app/Filament/System/Pages/Ops/Runs.php',
|
|
'app/Filament/System/Pages/Ops/Failures.php',
|
|
'app/Filament/System/Pages/Ops/Stuck.php',
|
|
'app/Filament/System/Pages/Security/AccessLogs.php',
|
|
'app/Filament/System/Pages/RepairWorkspaceOwners.php',
|
|
'app/Filament/Widgets/Dashboard/RecentDriftFindings.php',
|
|
'app/Filament/Widgets/Dashboard/RecentOperations.php',
|
|
'app/Livewire/BackupSetPolicyPickerTable.php',
|
|
'app/Livewire/EntraGroupCachePickerTable.php',
|
|
'app/Livewire/SettingsCatalogSettingsTable.php',
|
|
]);
|
|
|
|
/** @var Collection<int, string> $missing */
|
|
$missing = $paths
|
|
->filter(function (string $relativePath): bool {
|
|
$contents = file_get_contents(base_path($relativePath));
|
|
|
|
return ! is_string($contents) || ! str_contains($contents, '->defaultSort(');
|
|
})
|
|
->values();
|
|
|
|
expect($missing)->toBeEmpty('Missing explicit default sort declarations: '.implode(', ', $missing->all()));
|
|
});
|
|
|
|
it('declares domain-specific empty states across the standardized table surface inventory', function (): void {
|
|
$patternByPath = [
|
|
'app/Filament/Resources/TenantResource.php' => ['->emptyStateHeading('],
|
|
'app/Filament/Resources/PolicyResource.php' => ['->emptyStateHeading('],
|
|
'app/Filament/Resources/BackupSetResource.php' => ['->emptyStateHeading('],
|
|
'app/Filament/Resources/BackupScheduleResource.php' => ['->emptyStateHeading('],
|
|
'app/Filament/Resources/ProviderConnectionResource/Pages/ListProviderConnections.php' => ['getTableEmptyStateHeading', 'getTableEmptyStateDescription'],
|
|
'app/Filament/Resources/FindingResource.php' => ['->emptyStateHeading('],
|
|
'app/Filament/Resources/OperationRunResource.php' => ['->emptyStateHeading('],
|
|
'app/Filament/Resources/EntraGroupResource.php' => ['->emptyStateHeading('],
|
|
'app/Filament/Resources/AlertDeliveryResource.php' => ['->emptyStateHeading('],
|
|
'app/Filament/Resources/AlertRuleResource.php' => ['->emptyStateHeading('],
|
|
'app/Filament/Resources/AlertDestinationResource.php' => ['->emptyStateHeading('],
|
|
'app/Filament/Resources/BaselineProfileResource.php' => ['->emptyStateHeading('],
|
|
'app/Filament/Resources/BaselineSnapshotResource.php' => ['->emptyStateHeading('],
|
|
'app/Filament/Resources/InventoryItemResource.php' => ['->emptyStateHeading('],
|
|
'app/Filament/Resources/PolicyVersionResource.php' => ['->emptyStateHeading('],
|
|
'app/Filament/Resources/ReviewPackResource.php' => ['->emptyStateHeading('],
|
|
'app/Filament/Resources/Workspaces/WorkspaceResource.php' => ['->emptyStateHeading('],
|
|
'app/Filament/Resources/TenantResource/RelationManagers/TenantMembershipsRelationManager.php' => ['->emptyStateHeading('],
|
|
'app/Filament/Resources/Workspaces/RelationManagers/WorkspaceMembershipsRelationManager.php' => ['->emptyStateHeading('],
|
|
'app/Filament/Resources/BaselineProfileResource/RelationManagers/BaselineTenantAssignmentsRelationManager.php' => ['->emptyStateHeading('],
|
|
'app/Filament/Resources/BackupSetResource/RelationManagers/BackupItemsRelationManager.php' => ['->emptyStateHeading('],
|
|
'app/Filament/Resources/PolicyResource/RelationManagers/VersionsRelationManager.php' => ['->emptyStateHeading('],
|
|
'app/Filament/Resources/BackupScheduleResource/RelationManagers/BackupScheduleOperationRunsRelationManager.php' => ['->emptyStateHeading('],
|
|
'app/Filament/Pages/InventoryCoverage.php' => ['->emptyStateHeading('],
|
|
'app/Filament/System/Pages/Directory/Tenants.php' => ['->emptyStateHeading('],
|
|
'app/Filament/System/Pages/Directory/Workspaces.php' => ['->emptyStateHeading('],
|
|
'app/Filament/System/Pages/Ops/Runs.php' => ['->emptyStateHeading('],
|
|
'app/Filament/System/Pages/Ops/Failures.php' => ['->emptyStateHeading('],
|
|
'app/Filament/System/Pages/Ops/Stuck.php' => ['->emptyStateHeading('],
|
|
'app/Filament/System/Pages/Security/AccessLogs.php' => ['->emptyStateHeading('],
|
|
'app/Filament/System/Pages/RepairWorkspaceOwners.php' => ['->emptyStateHeading('],
|
|
'app/Filament/Widgets/Dashboard/RecentDriftFindings.php' => ['->emptyStateHeading('],
|
|
'app/Filament/Widgets/Dashboard/RecentOperations.php' => ['->emptyStateHeading('],
|
|
'app/Livewire/BackupSetPolicyPickerTable.php' => ['->emptyStateHeading('],
|
|
'app/Livewire/EntraGroupCachePickerTable.php' => ['->emptyStateHeading('],
|
|
'app/Livewire/SettingsCatalogSettingsTable.php' => ['->emptyStateHeading('],
|
|
];
|
|
|
|
$missing = [];
|
|
|
|
foreach ($patternByPath as $relativePath => $patterns) {
|
|
$contents = file_get_contents(base_path($relativePath));
|
|
|
|
if (! is_string($contents)) {
|
|
$missing[] = $relativePath;
|
|
|
|
continue;
|
|
}
|
|
|
|
foreach ($patterns as $pattern) {
|
|
if (! str_contains($contents, $pattern)) {
|
|
$missing[] = $relativePath;
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
expect($missing)->toBeEmpty('Missing standardized empty-state declarations: '.implode(', ', $missing));
|
|
});
|
|
|
|
it('keeps persistence declarations explicit on the designated critical resource lists', function (): void {
|
|
$paths = [
|
|
'app/Filament/Resources/TenantResource.php',
|
|
'app/Filament/Resources/PolicyResource.php',
|
|
'app/Filament/Resources/BackupSetResource.php',
|
|
'app/Filament/Resources/BackupScheduleResource.php',
|
|
'app/Filament/Resources/ProviderConnectionResource.php',
|
|
'app/Filament/Resources/FindingResource.php',
|
|
'app/Filament/Resources/OperationRunResource.php',
|
|
];
|
|
|
|
$missing = [];
|
|
|
|
foreach ($paths as $relativePath) {
|
|
$contents = file_get_contents(base_path($relativePath));
|
|
|
|
if (! is_string($contents)) {
|
|
$missing[] = $relativePath;
|
|
|
|
continue;
|
|
}
|
|
|
|
foreach (['->persistSearchInSession()', '->persistSortInSession()', '->persistFiltersInSession()'] as $pattern) {
|
|
if (! str_contains($contents, $pattern)) {
|
|
$missing[] = "{$relativePath} ({$pattern})";
|
|
}
|
|
}
|
|
}
|
|
|
|
expect($missing)->toBeEmpty('Missing persistence declarations: '.implode(', ', $missing));
|
|
});
|
|
|
|
it('uses the shared pagination profile helper on standardized surfaces', function (): void {
|
|
$paths = [
|
|
'app/Filament/Resources/TenantResource.php',
|
|
'app/Filament/Resources/PolicyResource.php',
|
|
'app/Filament/Resources/BackupSetResource.php',
|
|
'app/Filament/Resources/BackupScheduleResource.php',
|
|
'app/Filament/Resources/ProviderConnectionResource.php',
|
|
'app/Filament/Resources/FindingResource.php',
|
|
'app/Filament/Resources/OperationRunResource.php',
|
|
'app/Filament/Resources/EntraGroupResource.php',
|
|
'app/Filament/Resources/AlertDeliveryResource.php',
|
|
'app/Filament/Resources/AlertRuleResource.php',
|
|
'app/Filament/Resources/AlertDestinationResource.php',
|
|
'app/Filament/Resources/BaselineProfileResource.php',
|
|
'app/Filament/Resources/BaselineSnapshotResource.php',
|
|
'app/Filament/Resources/InventoryItemResource.php',
|
|
'app/Filament/Resources/PolicyVersionResource.php',
|
|
'app/Filament/Resources/ReviewPackResource.php',
|
|
'app/Filament/Resources/Workspaces/WorkspaceResource.php',
|
|
'app/Filament/Resources/TenantResource/RelationManagers/TenantMembershipsRelationManager.php',
|
|
'app/Filament/Resources/Workspaces/RelationManagers/WorkspaceMembershipsRelationManager.php',
|
|
'app/Filament/Resources/BaselineProfileResource/RelationManagers/BaselineTenantAssignmentsRelationManager.php',
|
|
'app/Filament/Resources/BackupSetResource/RelationManagers/BackupItemsRelationManager.php',
|
|
'app/Filament/Resources/PolicyResource/RelationManagers/VersionsRelationManager.php',
|
|
'app/Filament/Resources/BackupScheduleResource/RelationManagers/BackupScheduleOperationRunsRelationManager.php',
|
|
'app/Filament/Pages/InventoryCoverage.php',
|
|
'app/Filament/System/Pages/Directory/Tenants.php',
|
|
'app/Filament/System/Pages/Directory/Workspaces.php',
|
|
'app/Filament/System/Pages/Ops/Runs.php',
|
|
'app/Filament/System/Pages/Ops/Failures.php',
|
|
'app/Filament/System/Pages/Ops/Stuck.php',
|
|
'app/Filament/System/Pages/Security/AccessLogs.php',
|
|
'app/Filament/System/Pages/RepairWorkspaceOwners.php',
|
|
'app/Filament/Widgets/Dashboard/RecentDriftFindings.php',
|
|
'app/Filament/Widgets/Dashboard/RecentOperations.php',
|
|
'app/Livewire/BackupSetPolicyPickerTable.php',
|
|
'app/Livewire/EntraGroupCachePickerTable.php',
|
|
'app/Livewire/SettingsCatalogSettingsTable.php',
|
|
];
|
|
|
|
$missing = collect($paths)
|
|
->filter(function (string $relativePath): bool {
|
|
$contents = file_get_contents(base_path($relativePath));
|
|
|
|
return ! is_string($contents) || ! str_contains($contents, 'TablePaginationProfiles::');
|
|
})
|
|
->values()
|
|
->all();
|
|
|
|
expect($missing)->toBeEmpty('Missing pagination profile helper usage: '.implode(', ', $missing));
|
|
});
|