feat: ship agent-first mission control v0.2.57
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { createPinia, setActivePinia } from 'pinia'
|
||||
import {
|
||||
canApproveAgentProposal,
|
||||
canRejectAgentProposal,
|
||||
canRetryAgentProposal,
|
||||
getAgentProposalStatusMeta,
|
||||
type AgentProposalDto,
|
||||
} from '../src/api/agentProposals'
|
||||
import { apiFetch } from '../src/services/api'
|
||||
import { useAuthStore } from '../src/stores/auth'
|
||||
|
||||
const baseProposal: AgentProposalDto = {
|
||||
id: '0d2d33d7-bafa-4510-b135-c6a96021957a',
|
||||
source: 'manual',
|
||||
requestedName: 'Release Coordinator',
|
||||
requestedAgentId: 'release-coordinator',
|
||||
role: 'Delivery Operations',
|
||||
description: 'Coordinates releases.',
|
||||
model: null,
|
||||
emoji: null,
|
||||
avatar: null,
|
||||
workspace: '/managed/workspace-release-coordinator',
|
||||
files: [],
|
||||
status: 'awaiting_approval',
|
||||
requestedBy: 'bao',
|
||||
approvedBy: null,
|
||||
rejectedBy: null,
|
||||
rejectionReason: null,
|
||||
openClawAgentId: null,
|
||||
openClawWorkspace: null,
|
||||
error: null,
|
||||
revision: 1,
|
||||
createdAt: '2026-07-31T08:00:00.000Z',
|
||||
updatedAt: '2026-07-31T08:00:00.000Z',
|
||||
approvedAt: null,
|
||||
rejectedAt: null,
|
||||
completedAt: null,
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
setActivePinia(createPinia())
|
||||
const auth = useAuthStore()
|
||||
auth.initialized = true
|
||||
auth.applySession({
|
||||
accessToken: 'proposal-access-token',
|
||||
expiresAt: '2026-07-31T12:00:00.000Z',
|
||||
user: {
|
||||
id: 'bao',
|
||||
email: 'bao@nexus.local',
|
||||
displayName: 'Bao',
|
||||
role: 'owner',
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
vi.unstubAllGlobals()
|
||||
})
|
||||
|
||||
describe('agent proposal frontend contract', () => {
|
||||
it('maps lifecycle states to safe owner actions', () => {
|
||||
expect(getAgentProposalStatusMeta('awaiting_approval').label).toBe('Freigabe offen')
|
||||
expect(canApproveAgentProposal(baseProposal)).toBe(true)
|
||||
expect(canRejectAgentProposal(baseProposal)).toBe(true)
|
||||
expect(canRetryAgentProposal(baseProposal)).toBe(false)
|
||||
|
||||
const failed = { ...baseProposal, status: 'failed' }
|
||||
expect(canApproveAgentProposal(failed)).toBe(false)
|
||||
expect(canRejectAgentProposal(failed)).toBe(false)
|
||||
expect(canRetryAgentProposal(failed)).toBe(true)
|
||||
expect(canRetryAgentProposal({ ...baseProposal, status: 'in_doubt' })).toBe(true)
|
||||
})
|
||||
|
||||
it('preserves generated Request headers through the authenticated fetch boundary', async () => {
|
||||
const fetchMock = vi.fn(async () => new Response(JSON.stringify({ ok: true }), {
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
}))
|
||||
vi.stubGlobal('fetch', fetchMock)
|
||||
|
||||
const request = new Request('http://localhost/api/v1/openclaw/agent-proposals', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Idempotency-Key': 'agent-proposal-create:test',
|
||||
'X-Correlation-ID': 'd4f72d7d-6331-4bcc-87e8-e74480315073',
|
||||
},
|
||||
body: JSON.stringify({ name: 'Release Coordinator' }),
|
||||
})
|
||||
|
||||
await apiFetch(request)
|
||||
|
||||
const [, init] = fetchMock.mock.calls[0]
|
||||
const headers = new Headers(init?.headers)
|
||||
expect(headers.get('Authorization')).toBe('Bearer proposal-access-token')
|
||||
expect(headers.get('Content-Type')).toBe('application/json')
|
||||
expect(headers.get('Idempotency-Key')).toBe('agent-proposal-create:test')
|
||||
expect(headers.get('X-Correlation-ID')).toBe('d4f72d7d-6331-4bcc-87e8-e74480315073')
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user