Files
nexus/frontend/tests/agent-proposals.test.ts
T
AzuTear f5552218bc
CI - Build & Test / Backend (.NET) (push) Successful in 42s
CI - Build & Test / Frontend (Vue/TS) (push) Successful in 2m46s
CI - Build & Test / Security Check (push) Successful in 3s
CI - Build & Test / Deploy Nexus (push) Successful in 56s
feat: ship agent-first mission control v0.2.57
2026-07-31 22:39:47 +02:00

102 lines
3.2 KiB
TypeScript

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')
})
})