actingAs($user); setAdminPanelContext(); session()->put(WorkspaceContext::SESSION_KEY, (int) $environmentA->workspace_id); $legacyQueries = [ 'tenant' => ['tenant' => (string) $environmentA->getKey()], 'tenant_id' => ['tenant_id' => (int) $environmentA->getKey()], 'managed_environment_id' => ['managed_environment_id' => (int) $environmentA->getKey()], 'environment' => ['environment' => (string) $environmentA->getRouteKey()], 'tenant_scope' => ['tenant_scope' => 'environment'], 'tableFilters' => [ 'tableFilters' => [ 'managed_environment_id' => ['value' => (string) $environmentA->getKey()], ], ], ]; foreach ($legacyQueries as $query) { Livewire::withQueryParams($query) ->actingAs($user) ->test(Operations::class) ->assertSet('tableFilters.managed_environment_id.value', null) ->assertDontSee('Environment filter:') ->assertCanSeeTableRecords([$records['runA'], $records['runB']]); Livewire::withQueryParams($query) ->actingAs($user) ->test(ListAlertDeliveries::class) ->assertSet('tableFilters.managed_environment_id.value', null) ->assertDontSee('Environment filter:') ->assertCanSeeTableRecords([$records['deliveryA'], $records['deliveryB']]); Livewire::withQueryParams($query) ->actingAs($user) ->test(AuditLogPage::class) ->assertSet('tableFilters.managed_environment_id.value', null) ->assertDontSee('Environment filter:') ->assertCanSeeTableRecords([$records['auditA'], $records['auditB'], $records['auditWorkspace']]); } }); it('has_no_active_legacy_tenant_panel_routes', function (): void { $legacyRouteUris = collect(Route::getRoutes()) ->map(fn ($route): string => ltrim((string) $route->uri(), '/')) ->filter(fn (string $uri): bool => preg_match('#^admin/t(?:/|$)#', $uri) === 1) ->values(); $registeredProviders = require base_path('bootstrap/providers.php'); $tenantPanelProviders = collect($registeredProviders) ->filter(fn (string $provider): bool => str_contains($provider, 'TenantPanelProvider')) ->values(); expect($legacyRouteUris)->toBeEmpty() ->and($tenantPanelProviders)->toBeEmpty() ->and(file_exists(app_path('Providers/Filament/TenantPanelProvider.php')))->toBeFalse() ->and(file_exists(app_path('Filament/Providers/TenantPanelProvider.php')))->toBeFalse() ->and(Filament::getPanel('tenant'))->toBeNull(); $this->get('/admin/t/example')->assertNotFound(); }); it('allows_tenant_terms_only_in_provider_boundary_contexts', function (): void { $files = spec322LegacyGuardFiles([ base_path('app/Support/Navigation'), base_path('app/Filament/Pages/Monitoring/Operations.php'), base_path('app/Filament/Pages/Monitoring/FindingExceptionsQueue.php'), base_path('app/Filament/Pages/Governance/GovernanceInbox.php'), base_path('app/Filament/Pages/Governance/DecisionRegister.php'), base_path('app/Filament/Pages/Monitoring/EvidenceOverview.php'), base_path('app/Filament/Pages/Reviews/ReviewRegister.php'), base_path('app/Filament/Pages/Reviews/CustomerReviewWorkspace.php'), base_path('app/Filament/Resources/ProviderConnectionResource.php'), base_path('app/Filament/Resources/ProviderConnectionResource/Pages/ListProviderConnections.php'), base_path('routes/web.php'), ]); $hits = spec322LegacyPatternHits($files, [ '/\btenantPrefilterUrl\s*\(/', '/\bCanonicalAdminTenantFilterState\b/', '/\bWorkspaceScopedTenantRoutes\b/', '/\bTenantPageCategory\b/', '/\bEnsureFilamentTenantSelected\b/', '/'.'ensure-filament-'.'tenant-selected'.'/', '/\blastTenantId\s*\(/', '/\brememberedTenant\s*\(/', '/\brememberTenantContext\s*\(/', '/\bLAST_TENANT_IDS_SESSION_KEY\b/', '/\bTenantBound\b/', '/\bTenantScopedEvidence\b/', ]); expect($hits)->toBeEmpty("Retired Tenant platform-context terms remain:\n".implode("\n", $hits)); }); /** * @return array{0: \App\Models\User, 1: ManagedEnvironment, 2: ManagedEnvironment, 3: array} */ function spec322LegacyAliasFixture(): array { $environmentA = ManagedEnvironment::factory()->active()->create([ 'name' => 'Spec322 Alias Environment A', 'external_id' => 'spec322-alias-environment-a', ]); [$user, $environmentA] = createUserWithTenant(tenant: $environmentA, role: 'owner', workspaceRole: 'owner'); $environmentB = ManagedEnvironment::factory()->active()->create([ 'workspace_id' => (int) $environmentA->workspace_id, 'name' => 'Spec322 Alias Environment B', 'external_id' => 'spec322-alias-environment-b', ]); createUserWithTenant(tenant: $environmentB, user: $user, role: 'owner', workspaceRole: 'owner'); $runA = OperationRun::factory()->forTenant($environmentA)->create(['type' => 'policy.sync']); $runB = OperationRun::factory()->forTenant($environmentB)->create(['type' => 'inventory_sync']); $rule = AlertRule::factory()->create(['workspace_id' => (int) $environmentA->workspace_id]); $destination = AlertDestination::factory()->create(['workspace_id' => (int) $environmentA->workspace_id]); $deliveryA = AlertDelivery::factory()->create([ 'workspace_id' => (int) $environmentA->workspace_id, 'managed_environment_id' => (int) $environmentA->getKey(), 'alert_rule_id' => (int) $rule->getKey(), 'alert_destination_id' => (int) $destination->getKey(), 'status' => AlertDelivery::STATUS_FAILED, ]); $deliveryB = AlertDelivery::factory()->create([ 'workspace_id' => (int) $environmentA->workspace_id, 'managed_environment_id' => (int) $environmentB->getKey(), 'alert_rule_id' => (int) $rule->getKey(), 'alert_destination_id' => (int) $destination->getKey(), 'status' => AlertDelivery::STATUS_SENT, ]); $auditA = spec322LegacyAuditRecord($environmentA, 'Spec322 alias audit A'); $auditB = spec322LegacyAuditRecord($environmentB, 'Spec322 alias audit B'); $auditWorkspace = spec322LegacyAuditRecord(null, 'Spec322 workspace audit', [ 'workspace_id' => (int) $environmentA->workspace_id, ]); return [$user, $environmentA, $environmentB, compact( 'runA', 'runB', 'deliveryA', 'deliveryB', 'auditA', 'auditB', 'auditWorkspace', )]; } /** * @param array $attributes */ function spec322LegacyAuditRecord(?ManagedEnvironment $environment, string $summary, array $attributes = []): AuditLogModel { $workspaceId = array_key_exists('workspace_id', $attributes) ? (int) $attributes['workspace_id'] : (int) ($environment?->workspace_id); return AuditLogModel::query()->create(array_merge([ 'workspace_id' => $workspaceId, 'managed_environment_id' => $environment?->getKey(), 'actor_email' => 'spec322@example.test', 'actor_name' => 'Spec322 Operator', 'action' => 'operation.completed', 'status' => 'success', 'resource_type' => 'operation_run', 'resource_id' => '322', 'summary' => $summary, 'metadata' => [], 'recorded_at' => now(), ], $attributes)); } /** * @param list $roots * @return list */ function spec322LegacyGuardFiles(array $roots): array { $files = []; foreach ($roots as $root) { if (is_file($root)) { $files[] = $root; continue; } if (! is_dir($root)) { continue; } $iterator = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($root, FilesystemIterator::SKIP_DOTS), ); foreach ($iterator as $file) { if (! $file instanceof SplFileInfo || ! $file->isFile()) { continue; } if (! in_array($file->getExtension(), ['php', 'md'], true)) { continue; } $files[] = $file->getPathname(); } } sort($files); return array_values(array_unique($files)); } /** * @param list $files * @param list $patterns * @return list */ function spec322LegacyPatternHits(array $files, array $patterns): array { $hits = []; foreach ($files as $path) { $contents = file_get_contents($path); if (! is_string($contents)) { continue; } $lines = preg_split('/\R/', $contents) ?: []; foreach ($patterns as $pattern) { foreach ($lines as $lineNumber => $line) { if (preg_match($pattern, $line) !== 1) { continue; } $hits[] = str_replace(repo_path().'/', '', $path).':'.($lineNumber + 1).' -> '.trim($line); } } } return $hits; }