HuggingClaw-MissionControl / tests /agent-self-register.spec.ts
nyk
feat(refactor): ready for manual QA after main sync (#274)
b6ecafa unverified
Raw
History Blame Contribute Delete
4.82 kB
import { test, expect } from '@playwright/test'
import { API_KEY_HEADER, deleteTestAgent } from './helpers'
function uid() {
return `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`
}
test.describe('Agent Self-Registration', () => {
const cleanup: number[] = []
test.afterEach(async ({ request }) => {
for (const id of cleanup) {
await deleteTestAgent(request, id).catch(() => {})
}
cleanup.length = 0
})
// ── POST /api/agents/register ─────────────────────────
test('POST registers a new agent', async ({ request }) => {
const name = `self-reg-${uid()}`
const res = await request.post('/api/agents/register', {
headers: API_KEY_HEADER,
data: { name, role: 'coder' },
})
expect(res.status()).toBe(201)
const body = await res.json()
expect(body.registered).toBe(true)
expect(body.agent.name).toBe(name)
expect(body.agent.role).toBe('coder')
expect(body.agent.status).toBe('idle')
cleanup.push(body.agent.id)
})
test('POST is idempotent for existing agent', async ({ request }) => {
const name = `self-reg-idem-${uid()}`
// First registration
const res1 = await request.post('/api/agents/register', {
headers: API_KEY_HEADER,
data: { name, role: 'coder' },
})
expect(res1.status()).toBe(201)
const body1 = await res1.json()
cleanup.push(body1.agent.id)
// Second registration β€” should return existing
const res2 = await request.post('/api/agents/register', {
headers: API_KEY_HEADER,
data: { name, role: 'coder' },
})
expect(res2.status()).toBe(200)
const body2 = await res2.json()
expect(body2.registered).toBe(false)
expect(body2.agent.id).toBe(body1.agent.id)
})
test('POST rejects missing name', async ({ request }) => {
const res = await request.post('/api/agents/register', {
headers: API_KEY_HEADER,
data: { role: 'coder' },
})
expect(res.status()).toBe(400)
})
test('POST rejects invalid name characters', async ({ request }) => {
const res = await request.post('/api/agents/register', {
headers: API_KEY_HEADER,
data: { name: '../bad-agent', role: 'coder' },
})
expect(res.status()).toBe(400)
})
test('POST rejects name starting with dot', async ({ request }) => {
const res = await request.post('/api/agents/register', {
headers: API_KEY_HEADER,
data: { name: '.hidden-agent', role: 'coder' },
})
expect(res.status()).toBe(400)
})
test('POST rejects invalid role', async ({ request }) => {
const res = await request.post('/api/agents/register', {
headers: API_KEY_HEADER,
data: { name: `agent-${uid()}`, role: 'superuser' },
})
expect(res.status()).toBe(400)
const body = await res.json()
expect(body.error).toContain('role')
})
test('POST defaults role to agent', async ({ request }) => {
const name = `default-role-${uid()}`
const res = await request.post('/api/agents/register', {
headers: API_KEY_HEADER,
data: { name },
})
expect(res.status()).toBe(201)
const body = await res.json()
expect(body.agent.role).toBe('agent')
cleanup.push(body.agent.id)
})
test('POST accepts capabilities and framework', async ({ request }) => {
const name = `capable-${uid()}`
const res = await request.post('/api/agents/register', {
headers: API_KEY_HEADER,
data: {
name,
role: 'coder',
capabilities: ['code-review', 'testing'],
framework: 'claude-sdk',
},
})
expect(res.status()).toBe(201)
const body = await res.json()
expect(body.agent.name).toBe(name)
cleanup.push(body.agent.id)
// Verify capabilities stored in config
const agentRes = await request.get('/api/agents', { headers: API_KEY_HEADER })
const agentBody = await agentRes.json()
const found = agentBody.agents.find((a: any) => a.name === name)
expect(found).toBeDefined()
expect(found.config.capabilities).toEqual(['code-review', 'testing'])
expect(found.config.framework).toBe('claude-sdk')
})
test('POST appears in agents list after registration', async ({ request }) => {
const name = `listed-${uid()}`
const regRes = await request.post('/api/agents/register', {
headers: API_KEY_HEADER,
data: { name, role: 'tester' },
})
const regBody = await regRes.json()
cleanup.push(regBody.agent.id)
const listRes = await request.get('/api/agents', { headers: API_KEY_HEADER })
const listBody = await listRes.json()
const found = listBody.agents.find((a: any) => a.name === name)
expect(found).toBeDefined()
expect(found.role).toBe('tester')
expect(found.status).toBe('idle')
})
})