mirror of
https://github.com/hanzo-apps/hanzo.ai.git
synced 2026-10-29 07:20:43 +00:00
Every import, the catalog pin and the docs name @hanzo/app and github.com/hanzoai/app. lib/rooms.ts is lib/app.ts and components/rooms.tsx is components/app.tsx.
117 lines
3.8 KiB
TypeScript
117 lines
3.8 KiB
TypeScript
import { test, expect } from '@playwright/test'
|
|
import {
|
|
reads,
|
|
runName,
|
|
runs,
|
|
runOf,
|
|
start,
|
|
NAMESPACE,
|
|
AGENT_QUEUE,
|
|
AGENT_WORKFLOW,
|
|
} from '@hanzo/app/lib/durable'
|
|
import type { AiClient } from '@hanzo/ai'
|
|
|
|
test.describe('durable execution engine unit tests', () => {
|
|
test('reads() maps status strings into human terms', () => {
|
|
expect(reads(undefined)).toBe('unknown')
|
|
expect(reads('')).toBe('unknown')
|
|
expect(reads('WORKFLOW_EXECUTION_STATUS_RUNNING')).toBe('running')
|
|
expect(reads('WORKFLOW_EXECUTION_STATUS_COMPLETED')).toBe('done')
|
|
expect(reads('WORKFLOW_EXECUTION_STATUS_FAILED')).toBe('failed')
|
|
expect(reads('WORKFLOW_EXECUTION_STATUS_CANCELED')).toBe('canceled')
|
|
expect(reads('WORKFLOW_EXECUTION_STATUS_TERMINATED')).toBe('stopped')
|
|
expect(reads('WORKFLOW_EXECUTION_STATUS_TIMED_OUT')).toBe('timed out')
|
|
expect(reads('WORKFLOW_EXECUTION_STATUS_PAUSED')).toBe('paused')
|
|
expect(reads('CUSTOM_STATUS')).toBe('custom_status')
|
|
})
|
|
|
|
test('runName() derives workflow ID deterministically', () => {
|
|
expect(runName('hanzo', 101)).toBe('card-hanzo-101')
|
|
expect(runName('cloud', 5)).toBe('card-cloud-5')
|
|
})
|
|
|
|
test('constants match platform configuration', () => {
|
|
expect(NAMESPACE).toBe('default')
|
|
expect(AGENT_QUEUE).toBe('agents')
|
|
expect(AGENT_WORKFLOW).toBe('AgentWorkflow')
|
|
})
|
|
|
|
test('runs() maps execution lists from tasks API', async () => {
|
|
const mockClient = {
|
|
http: {
|
|
json: async () => ({
|
|
executions: [
|
|
{
|
|
execution: { workflowId: 'card-hanzo-1', runId: 'run_1' },
|
|
type: { name: 'AgentWorkflow' },
|
|
status: 'WORKFLOW_EXECUTION_STATUS_RUNNING',
|
|
startTime: '2026-09-01T00:00:00Z',
|
|
historyLength: 4,
|
|
taskQueue: 'agents',
|
|
},
|
|
],
|
|
}),
|
|
},
|
|
} as unknown as AiClient
|
|
|
|
const list = await runs(mockClient)
|
|
expect(list.length).toBe(1)
|
|
expect(list[0].workflowId).toBe('card-hanzo-1')
|
|
expect(list[0].status).toBe('WORKFLOW_EXECUTION_STATUS_RUNNING')
|
|
expect(list[0].runId).toBe('run_1')
|
|
expect(list[0].type).toBe('AgentWorkflow')
|
|
})
|
|
|
|
test('runOf() finds newest execution attempt', async () => {
|
|
const mockClient = {
|
|
http: {
|
|
json: async () => ({
|
|
executions: [
|
|
{
|
|
execution: { workflowId: 'card-hanzo-2', runId: 'run_old' },
|
|
status: 'WORKFLOW_EXECUTION_STATUS_FAILED',
|
|
},
|
|
{
|
|
execution: { workflowId: 'card-hanzo-2', runId: 'run_new' },
|
|
status: 'WORKFLOW_EXECUTION_STATUS_RUNNING',
|
|
},
|
|
],
|
|
}),
|
|
},
|
|
} as unknown as AiClient
|
|
|
|
const run = await runOf(mockClient, 'hanzo', 2)
|
|
expect(run).toBeDefined()
|
|
expect(run?.runId).toBe('run_new')
|
|
expect(run?.status).toBe('WORKFLOW_EXECUTION_STATUS_RUNNING')
|
|
})
|
|
|
|
test('start() dispatches durable workflow with requestId idempotency key', async () => {
|
|
let capturedBody: any = null
|
|
const mockClient = {
|
|
http: {
|
|
json: async (req: any) => {
|
|
capturedBody = req.body
|
|
return {
|
|
execution: { workflowId: req.body.workflowId, runId: 'run_created' },
|
|
status: 'WORKFLOW_EXECUTION_STATUS_RUNNING',
|
|
}
|
|
},
|
|
},
|
|
} as unknown as AiClient
|
|
|
|
const res = await start(mockClient, 'hanzo', 10, {
|
|
title: 'Fix issue 10',
|
|
queue: AGENT_QUEUE,
|
|
type: AGENT_WORKFLOW,
|
|
})
|
|
|
|
expect(capturedBody).toBeDefined()
|
|
expect(capturedBody.workflowId).toBe('card-hanzo-10')
|
|
expect(capturedBody.requestId).toBe('card-hanzo-10')
|
|
expect(capturedBody.taskQueue.name).toBe(AGENT_QUEUE)
|
|
expect(res.workflowId).toBe('card-hanzo-10')
|
|
expect(res.runId).toBe('run_created')
|
|
})
|
|
})
|