import { beforeEach, describe, expect, it, vi } from 'vitest' import { createPinia, setActivePinia } from 'pinia' import { startOpenClawRun, type OpenClawRunDto, } from '../src/api/openClawRuns' import { useAuthStore } from '../src/stores/auth' const run: OpenClawRunDto = { id: '98f927bb-3df8-44d0-9ec9-cd98cdcf12db', title: 'Review the task', prompt: 'Review task 42 and propose the next action.', agentId: 'iris', sessionKey: 'agent:iris:main', status: 'running', taskId: null, projectId: null, openClawRunId: 'openclaw-run-42', retriedFromRunId: null, correlationId: 'correlation-42', actor: 'bao', lastError: null, lastGatewaySequence: 42, sequenceGapDetected: false, canStop: true, canRetry: false, canResume: false, resumeCapabilityMessage: 'Same-run resume is not advertised.', createdAt: '2026-07-30T10:00:00.000Z', updatedAt: '2026-07-30T10:00:01.000Z', startedAt: '2026-07-30T10:00:01.000Z', finishedAt: null, } beforeEach(() => { setActivePinia(createPinia()) const auth = useAuthStore() auth.initialized = true auth.applySession({ accessToken: 'test-access-token', expiresAt: '2026-07-30T12:00:00.000Z', user: { id: 'bao', email: 'bao@nexus.local', displayName: 'Bao', role: 'owner', }, }) }) describe('OpenClaw durable runs', () => { it('sends idempotency, correlation and W3C trace metadata for a dispatch', async () => { const fetchMock = vi.fn(async () => new Response(JSON.stringify({ ok: true, state: 'running', message: 'Run dispatched.', run, resultRun: null, completedAt: '2026-07-30T10:00:01.000Z', }), { status: 201, headers: { 'Content-Type': 'application/json' }, })) vi.stubGlobal('fetch', fetchMock) const result = await startOpenClawRun({ prompt: run.prompt, agentId: run.agentId, sessionKey: run.sessionKey, }) expect(result.run.id).toBe(run.id) const [, init] = fetchMock.mock.calls[0] const headers = new Headers(init?.headers) expect(headers.get('Authorization')).toBe('Bearer test-access-token') expect(headers.get('Idempotency-Key')).toMatch(/^openclaw-run-start:/) expect(headers.get('X-Correlation-ID')).toMatch(/^[0-9a-f-]{36}$/i) expect(headers.get('traceparent')).toMatch(/^00-[0-9a-f]{32}-[0-9a-f]{16}-01$/) }) })