create([ 'tenant_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'provider.connection.check', 'status' => 'completed', 'outcome' => 'blocked', 'initiator_name' => 'System', ]); $this->actingAs($user); Bus::fake(); Filament::setTenant(null, true); $session = [ WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id, ]; assertNoOutboundHttp(function () use ($run, $session): void { $this->withSession($session) ->get(route('admin.operations.index')) ->assertOk() ->assertSee('Scope: Workspace — all tenants'); $this->withSession($session) ->get(route('admin.operations.view', ['run' => (int) $run->getKey()])) ->assertOk() ->assertSee('Scope: Workspace — all tenants'); $this->withSession($session) ->get(route('admin.monitoring.alerts')) ->assertOk() ->assertSee('Scope: Workspace — all tenants'); $this->withSession($session) ->get(route('admin.monitoring.audit-log')) ->assertOk() ->assertSee('Scope: Workspace — all tenants'); }); Bus::assertNothingDispatched(); })->group('ops-ux'); it('shows back to tenant on run detail when tenant context is active and entitled', function (): void { [$user, $tenant] = createUserWithTenant(role: 'owner'); $run = OperationRun::factory()->create([ 'tenant_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'policy.sync', 'status' => 'queued', 'outcome' => 'pending', ]); $this->actingAs($user); Filament::setTenant($tenant, true); $response = $this->withSession([ WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id, ])->get(route('admin.operations.view', ['run' => (int) $run->getKey()])); $response ->assertOk() ->assertSee('← Back to '.$tenant->name) ->assertSee(TenantDashboard::getUrl(panel: 'tenant', tenant: $tenant), false) ->assertSee('Show all operations') ->assertDontSee('Back to Operations'); expect(substr_count((string) $response->getContent(), '← Back to '.$tenant->name))->toBe(1); })->group('ops-ux'); it('shows back to tenant when filament tenant is absent but last tenant memory exists', function (): void { [$user, $tenant] = createUserWithTenant(role: 'owner'); $run = OperationRun::factory()->create([ 'tenant_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'policy.sync', 'status' => 'queued', 'outcome' => 'pending', ]); $this->actingAs($user); Filament::setTenant(null, true); $workspaceId = (int) $tenant->workspace_id; $lastTenantMap = [(string) $workspaceId => (int) $tenant->getKey()]; $response = $this->withSession([ WorkspaceContext::SESSION_KEY => $workspaceId, WorkspaceContext::LAST_TENANT_IDS_SESSION_KEY => $lastTenantMap, ])->get(route('admin.operations.view', ['run' => (int) $run->getKey()])); $response ->assertOk() ->assertSee('← Back to '.$tenant->name) ->assertSee(TenantDashboard::getUrl(panel: 'tenant', tenant: $tenant), false) ->assertSee('Show all operations') ->assertDontSee('Back to Operations'); })->group('ops-ux'); it('shows no tenant return affordance when active and last tenant contexts are not entitled', function (): void { [$user, $entitledTenant] = createUserWithTenant(role: 'owner'); $nonEntitledTenant = Tenant::factory()->create([ 'workspace_id' => (int) $entitledTenant->workspace_id, ]); $run = OperationRun::factory()->create([ 'tenant_id' => (int) $entitledTenant->getKey(), 'workspace_id' => (int) $entitledTenant->workspace_id, 'type' => 'policy.sync', 'status' => 'queued', 'outcome' => 'pending', ]); $this->actingAs($user); Filament::setTenant($nonEntitledTenant, true); $workspaceId = (int) $entitledTenant->workspace_id; $response = $this->withSession([ WorkspaceContext::SESSION_KEY => $workspaceId, WorkspaceContext::LAST_TENANT_IDS_SESSION_KEY => [(string) $workspaceId => (int) $nonEntitledTenant->getKey()], ])->get(route('admin.operations.view', ['run' => (int) $run->getKey()])); $response ->assertOk() ->assertSee('Back to Operations') ->assertDontSee('← Back to '.$nonEntitledTenant->name) ->assertDontSee('Show all operations'); })->group('ops-ux'); it('returns 404 for non-member workspace access to /admin/operations', function (): void { $user = User::factory()->create(); $workspace = Workspace::factory()->create(); $this->actingAs($user) ->withSession([WorkspaceContext::SESSION_KEY => (int) $workspace->getKey()]) ->get(route('admin.operations.index')) ->assertNotFound(); })->group('ops-ux'); it('returns 404 for non-entitled tenant dashboard direct access', function (): void { $tenant = Tenant::factory()->create(); $user = User::factory()->create(); WorkspaceMembership::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, 'user_id' => (int) $user->getKey(), 'role' => 'owner', ]); $this->actingAs($user) ->withSession([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id]) ->get(TenantDashboard::getUrl(panel: 'tenant', tenant: $tenant)) ->assertNotFound(); })->group('ops-ux'); it('keeps member-without-capability workflow start denial as 403 with no run side effects', function (): void { [$user, $tenant] = createUserWithTenant(role: 'operator'); $this->actingAs($user); Filament::setTenant($tenant, true); $this->withSession([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id]) ->get(RestoreRunResource::getUrl('create', tenant: $tenant)) ->assertForbidden(); expect(OperationRun::query() ->where('tenant_id', (int) $tenant->getKey()) ->exists())->toBeFalse(); })->group('ops-ux'); it('does not mutate workspace or last-tenant session memory on /admin/operations', function (): void { [$user, $tenant] = createUserWithTenant(role: 'owner'); $this->actingAs($user); Filament::setTenant($tenant, true); $workspaceId = (int) $tenant->workspace_id; $lastTenantMap = [(string) $workspaceId => (int) $tenant->getKey()]; $response = $this->withSession([ WorkspaceContext::SESSION_KEY => $workspaceId, WorkspaceContext::LAST_TENANT_IDS_SESSION_KEY => $lastTenantMap, ])->get(route('admin.operations.index')); $response->assertOk(); $response->assertSessionHas(WorkspaceContext::SESSION_KEY, $workspaceId); $response->assertSessionHas(WorkspaceContext::LAST_TENANT_IDS_SESSION_KEY, $lastTenantMap); })->group('ops-ux'); it('shows tenant scope label when tenant context is active', function (): void { [$user, $tenant] = createUserWithTenant(role: 'owner'); $this->actingAs($user); Filament::setTenant($tenant, true); $this->withSession([ WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id, ])->get(route('admin.operations.index')) ->assertOk() ->assertSee('Scope: Tenant — '.$tenant->name) ->assertDontSee('Scope: Workspace — all tenants'); })->group('ops-ux'); it('does not create audit entries when viewing operate hub pages', function (): void { [$user, $tenant] = createUserWithTenant(role: 'owner'); $run = OperationRun::factory()->create([ 'tenant_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => 'policy.sync', 'status' => 'queued', 'outcome' => 'pending', ]); $this->actingAs($user); Filament::setTenant(null, true); $before = (int) AuditLog::query()->count(); $session = [ WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id, ]; $this->withSession($session) ->get(route('admin.operations.index')) ->assertOk(); $this->withSession($session) ->get(route('admin.operations.view', ['run' => (int) $run->getKey()])) ->assertOk(); $this->withSession($session) ->get(route('admin.monitoring.alerts')) ->assertOk(); $this->withSession($session) ->get(route('admin.monitoring.audit-log')) ->assertOk(); expect((int) AuditLog::query()->count())->toBe($before); })->group('ops-ux');