TenantAtlas/apps/platform/tests/Feature/Filament/GovernanceArtifacts/GovernanceArtifactLegacyTenantPanelGuardTest.php
ahmido f50d57370f feat: cut over workspace-first admin environment surfaces (#341)
## Summary
- cut over the admin runtime to the workspace-first environment and operations routes from spec 280
- retarget governance artifact resources, related navigation, and operation drillthroughs to the surviving admin panel contract from spec 282
- add focused feature and browser coverage plus spec close-out updates for the shipped 280/282 slice

## Validation
- `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent`
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/WorkspaceFoundation tests/Feature/Workspaces tests/Feature/ManagedEnvironment tests/Feature/RequiredPermissions tests/Feature/Operations tests/Feature/MonitoringOperationsTest.php`
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Browser/Spec280WorkspaceTenancyEnvironmentRoutingSmokeTest.php`
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament/GovernanceArtifacts/GovernanceArtifactAdminPanelRegistrationTest.php tests/Feature/Filament/GovernanceArtifacts/GovernanceArtifactEnvironmentContextTest.php tests/Feature/Filament/GovernanceArtifacts/GovernanceArtifactDeepLinkContractTest.php tests/Feature/Filament/GovernanceArtifacts/GovernanceArtifactLegacyTenantPanelGuardTest.php`
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Browser/Spec282GovernanceArtifactRetargetingSmokeTest.php`

## Notes
- provider registration remains in `apps/platform/bootstrap/providers.php`
- Filament stays on v5 with Livewire v4 semantics
- touched searchable governance surfaces remain truthful or disabled in the same slice

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #341
2026-05-07 23:50:36 +00:00

117 lines
4.8 KiB
PHP

<?php
declare(strict_types=1);
use App\Filament\Resources\TenantReviewResource;
use App\Models\ManagedEnvironment;
use App\Models\Workspace;
use Tests\Support\OpsUx\SourceFileScanner;
/**
* @return list<string>
*/
function governanceArtifactLegacyTenantGuardedFiles(): array
{
$root = SourceFileScanner::projectRoot();
return [
$root.'/app/Filament/Pages/Reviews/CustomerReviewWorkspace.php',
$root.'/app/Filament/Pages/Reviews/ReviewRegister.php',
$root.'/app/Filament/Resources/BackupScheduleResource.php',
$root.'/app/Filament/Resources/BackupSetResource.php',
$root.'/app/Filament/Resources/EvidenceSnapshotResource.php',
$root.'/app/Filament/Resources/FindingExceptionResource.php',
$root.'/app/Filament/Resources/FindingResource.php',
$root.'/app/Filament/Resources/InventoryItemResource.php',
$root.'/app/Filament/Resources/PolicyResource.php',
$root.'/app/Filament/Resources/PolicyVersionResource.php',
$root.'/app/Filament/Resources/RestoreRunResource.php',
$root.'/app/Filament/Resources/ReviewPackResource.php',
$root.'/app/Filament/Resources/StoredReportResource.php',
$root.'/app/Filament/Resources/TenantReviewResource.php',
$root.'/app/Support/GovernanceInbox/GovernanceInboxSectionBuilder.php',
$root.'/app/Support/Navigation/RelatedNavigationResolver.php',
$root.'/app/Support/OperationRunLinks.php',
$root.'/app/Support/SupportDiagnostics/SupportDiagnosticBundleBuilder.php',
$root.'/app/Support/Ui/GovernanceArtifactTruth/ArtifactTruthPresenter.php',
];
}
/**
* @return list<array{pattern: string, reason: string}>
*/
function governanceArtifactLegacyTenantForbiddenPatterns(): array
{
return [
[
'pattern' => "/panel:\\s*'tenant'/",
'reason' => 'Touched governance artifact surfaces must not emit tenant-panel URLs directly.',
],
[
'pattern' => '/\\/admin\\/t\\//',
'reason' => 'Touched governance artifact surfaces must not hardcode legacy /admin/t route language.',
],
[
'pattern' => "/TenantReviewResource::tenantScopedUrl\\([^\\n]*,\\s*'tenant'\\)/",
'reason' => 'Touched review drillthrough call-sites must not carry a stale tenant-panel hint.',
],
[
'pattern' => '/\\bManagedEnvironment::current\\s*\\(/',
'reason' => 'Touched governance artifact surfaces must not rely on tenant-panel-only current-environment fallbacks.',
],
[
'pattern' => '/\\bFilament::getTenant\\s*\\(/',
'reason' => 'Touched governance artifact surfaces must resolve admin context through the shared panel resolver, not raw Filament tenant reads.',
],
[
'pattern' => "/getCurrentPanel\\(\\)\\?->getId\\(\\)\\s*===\\s*'admin'/",
'reason' => 'Touched governance artifact resources must not stay hidden behind admin-only registration guards.',
],
];
}
it('keeps touched governance artifact sources free of tenant-panel route language and fallback guards', function (): void {
$violations = [];
foreach (governanceArtifactLegacyTenantGuardedFiles() as $path) {
$source = SourceFileScanner::read($path);
$lines = preg_split('/\R/', $source) ?: [];
foreach ($lines as $index => $line) {
foreach (governanceArtifactLegacyTenantForbiddenPatterns() as $pattern) {
if (preg_match($pattern['pattern'], $line) !== 1) {
continue;
}
$violations[] = [
'file' => SourceFileScanner::relativePath($path),
'line' => $index + 1,
'snippet' => SourceFileScanner::snippet($source, $index + 1),
'reason' => $pattern['reason'],
];
}
}
}
expect($violations)->toBeEmpty();
})->group('surface-guard');
it('keeps tenant review scoped urls on workspace-first admin routes even when a legacy tenant hint is supplied', function (): void {
$tenant = ManagedEnvironment::factory()->create();
[$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner', setUiContext: false);
$snapshot = seedTenantReviewEvidence($tenant);
$review = composeTenantReviewForTest($tenant, $user, $snapshot);
$workspace = Workspace::query()->whereKey((int) $tenant->workspace_id)->firstOrFail();
setAdminPanelContext();
$path = parse_url(
TenantReviewResource::tenantScopedUrl('view', ['record' => $review], $tenant, 'tenant'),
PHP_URL_PATH,
);
expect($path)
->toBe('/admin/workspaces/'.$workspace->getRouteKey().'/environments/'.$tenant->getRouteKey().'/reviews/'.$review->getRouteKey())
->not->toContain('/admin/t/');
})->group('surface-guard');