toBeTrue() ->and(FindingExceptionResource::shouldRegisterNavigation())->toBeTrue() ->and(InventoryItemResource::shouldRegisterNavigation())->toBeTrue() ->and(PolicyResource::shouldRegisterNavigation())->toBeTrue() ->and(PolicyVersionResource::shouldRegisterNavigation())->toBeTrue() ->and(BackupScheduleResource::shouldRegisterNavigation())->toBeTrue() ->and(BackupSetResource::shouldRegisterNavigation())->toBeTrue() ->and(RestoreRunResource::shouldRegisterNavigation())->toBeTrue() ->and(TenantReviewResource::shouldRegisterNavigation())->toBeTrue(); }); it('builds workspace-first admin urls for governance resources', function (): void { Filament::setCurrentPanel('admin'); $workspace = Workspace::factory()->create([ 'name' => 'Spec 282 Workspace', 'slug' => 'spec-282-workspace', ]); $tenant = ManagedEnvironment::factory()->active()->create([ 'workspace_id' => (int) $workspace->getKey(), 'name' => 'Spec 282 Production', 'slug' => 'spec-282-production', ]); $expectedPrefix = '/admin/workspaces/'.$workspace->getRouteKey().'/environments/'.$tenant->getRouteKey().'/'; $searchableResources = []; foreach ([ InventoryItemResource::class, PolicyResource::class, PolicyVersionResource::class, BackupScheduleResource::class, BackupSetResource::class, RestoreRunResource::class, FindingResource::class, FindingExceptionResource::class, EvidenceSnapshotResource::class, TenantReviewResource::class, ReviewPackResource::class, StoredReportResource::class, ] as $resourceClass) { $path = parse_url($resourceClass::getUrl('index', panel: 'admin', tenant: $tenant), PHP_URL_PATH); expect($path) ->toBeString() ->toStartWith($expectedPrefix) ->not->toContain('/admin/t/'); } }); it('returns 404 for governance artifact routes when the workspace and environment pair is mismatched', function (): void { Filament::setCurrentPanel('admin'); $workspace = Workspace::factory()->create([ 'name' => 'Spec 282 Primary Workspace', 'slug' => 'spec-282-primary-workspace', ]); $otherWorkspace = Workspace::factory()->create([ 'name' => 'Spec 282 Secondary Workspace', 'slug' => 'spec-282-secondary-workspace', ]); $tenant = ManagedEnvironment::factory()->active()->create([ 'workspace_id' => (int) $workspace->getKey(), 'name' => 'Spec 282 Production', 'slug' => 'spec-282-production', ]); $user = User::factory()->create(); foreach ([$workspace, $otherWorkspace] as $memberWorkspace) { WorkspaceMembership::factory()->create([ 'workspace_id' => (int) $memberWorkspace->getKey(), 'user_id' => (int) $user->getKey(), 'role' => 'owner', ]); } $user->tenants()->syncWithoutDetaching([ (int) $tenant->getKey() => ['role' => 'owner'], ]); $report = StoredReport::factory() ->permissionPosture() ->create([ 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, ]); $this->actingAs($user) ->withSession([ WorkspaceContext::SESSION_KEY => (int) $otherWorkspace->getKey(), ]) ->get(FindingResource::getUrl('index', ['workspace' => $otherWorkspace], panel: 'admin', tenant: $tenant)) ->assertNotFound(); $this->actingAs($user) ->withSession([ WorkspaceContext::SESSION_KEY => (int) $otherWorkspace->getKey(), ]) ->get(StoredReportResource::getUrl('view', ['workspace' => $otherWorkspace, 'record' => $report], panel: 'admin', tenant: $tenant)) ->assertNotFound(); }); it('keeps touched searchable governance resources on truthful destinations', function (): void { $tenant = ManagedEnvironment::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner', setUiContext: false); $this->actingAs($user); setAdminPanelContext(); session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id); session()->put(WorkspaceContext::LAST_TENANT_IDS_SESSION_KEY, [ (string) $tenant->workspace_id => (int) $tenant->getKey(), ]); $searchableResources = []; foreach ([ InventoryItemResource::class, PolicyResource::class, PolicyVersionResource::class, BackupScheduleResource::class, BackupSetResource::class, RestoreRunResource::class, FindingResource::class, FindingExceptionResource::class, EvidenceSnapshotResource::class, TenantReviewResource::class, ReviewPackResource::class, StoredReportResource::class, ] as $resourceClass) { if (! $resourceClass::canGloballySearch()) { continue; } $searchableResources[] = $resourceClass; } expect($searchableResources)->toBeArray(); foreach ($searchableResources as $resourceClass) { expect($resourceClass::hasPage('view') || $resourceClass::hasPage('edit')) ->toBeTrue($resourceClass.' must keep a truthful global-search destination on the admin panel.'); } });