create([ 'workspace_id' => (int) $tenant->workspace_id, 'name' => 'Foreign Query Tenant', 'external_id' => 'foreign-query-tenant', ]); $response = $this->actingAs($user) ->get("/admin/tenants/{$tenant->external_id}/required-permissions?tenant={$otherTenant->external_id}&tenant_id={$otherTenant->getKey()}&status=all") ->assertSuccessful(); $response ->assertSee($tenant->getFilamentName()) ->assertDontSee($otherTenant->name); }); it('keeps filter state usable without redefining tenant scope', function (): void { [$user, $tenant] = createUserWithTenant(role: 'readonly'); config()->set('intune_permissions.permissions', [ [ 'key' => 'Tenant.Read.All', 'type' => 'application', 'description' => 'Tenant read permission', 'features' => ['backup'], ], ]); config()->set('entra_permissions.permissions', []); TenantPermission::create([ 'tenant_id' => (int) $tenant->getKey(), 'permission_key' => 'Tenant.Read.All', 'status' => 'granted', 'details' => ['source' => 'db'], 'last_checked_at' => now(), ]); $response = $this->actingAs($user) ->get("/admin/tenants/{$tenant->external_id}/required-permissions?status=present&type=application&search=Tenant") ->assertSuccessful(); $response ->assertSee($tenant->getFilamentName()) ->assertSee('Tenant.Read.All'); }); it('returns 404 when the current workspace no longer matches the tenant route scope', function (): void { $workspaceA = Workspace::factory()->create(); $workspaceB = Workspace::factory()->create(); $user = User::factory()->create(); $tenant = Tenant::factory()->create([ 'workspace_id' => (int) $workspaceA->getKey(), 'external_id' => 'tenant-required-permissions-404', ]); createUserWithTenant( tenant: $tenant, user: $user, role: 'readonly', workspaceRole: 'readonly', ); WorkspaceMembership::factory()->create([ 'workspace_id' => (int) $workspaceB->getKey(), 'user_id' => (int) $user->getKey(), 'role' => 'readonly', ]); session()->put(WorkspaceContext::SESSION_KEY, (int) $workspaceB->getKey()); $this->actingAs($user) ->get('/admin/tenants/'.$tenant->external_id.'/required-permissions') ->assertNotFound(); }); it('seeds native table state from deeplink filters without letting query values redefine the route tenant', function (): void { [$user, $tenant] = createUserWithTenant(role: 'readonly'); $otherTenant = Tenant::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, 'name' => 'Ignored Query Tenant', 'external_id' => 'ignored-query-tenant', ]); config()->set('intune_permissions.permissions', [ [ 'key' => 'Tenant.Read.All', 'type' => 'application', 'description' => 'Tenant read permission', 'features' => ['backup'], ], ]); config()->set('entra_permissions.permissions', []); TenantPermission::query()->create([ 'tenant_id' => (int) $tenant->getKey(), 'permission_key' => 'Tenant.Read.All', 'status' => 'granted', 'details' => ['source' => 'db'], 'last_checked_at' => now(), ]); $this->actingAs($user); setAdminPanelContext(); session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id); $component = Livewire::withQueryParams([ 'tenant' => $tenant->external_id, 'tenant_id' => (string) $otherTenant->getKey(), 'status' => 'present', 'type' => 'application', 'features' => ['backup'], 'search' => 'Tenant', ])->test(TenantRequiredPermissions::class); $component ->assertSet('tableFilters.status.value', 'present') ->assertSet('tableFilters.type.value', 'application') ->assertSet('tableFilters.features.values', ['backup']) ->assertSet('tableSearch', 'Tenant'); expect($component->instance()->currentTenant()?->is($tenant))->toBeTrue(); });