Files
memind/server/portal-goal-run-routes.test.mjs
T
john 666db0b939 feat(goal-run): add multi-checkpoint goal orchestration with H5 and admin surfaces.
Persist goal runs in MySQL, bind agent runs to checkpoints, expose awaiting-approval
UX in chat, and add admin inspection routes with local verify scripts.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-01 17:03:16 +08:00

227 lines
6.1 KiB
JavaScript

import assert from 'node:assert/strict';
import test from 'node:test';
import { attachPortalGoalRunRoutes } from './portal-goal-run-routes.mjs';
function createRouterRecorder() {
const routes = new Map();
return {
routes,
get(path, handler) {
routes.set(`GET ${path}`, handler);
},
post(path, handler) {
routes.set(`POST ${path}`, handler);
},
delete(path, handler) {
routes.set(`DELETE ${path}`, handler);
},
};
}
function createResponseRecorder() {
return {
statusCode: 200,
body: undefined,
status(code) {
this.statusCode = code;
return this;
},
json(body) {
this.body = body;
return this;
},
};
}
function createRequest(overrides = {}) {
return {
body: {},
query: {},
params: {},
currentUser: { id: 'user-canary' },
...overrides,
};
}
function enabledGoalRunService(overrides = {}) {
return {
async createGoalRun(input) {
return {
id: 'goal-1',
title: input.title,
intentSummary: input.intentSummary,
checkpoints: [{ id: 'cp-1', title: '启动', status: 'pending' }],
currentCheckpointId: 'cp-1',
};
},
async listGoalRuns() {
return [{ id: 'goal-1', title: '长期任务', status: 'active' }];
},
async getGoalRun({ goalRunId }) {
if (goalRunId !== 'goal-1') return null;
return {
id: 'goal-1',
title: '长期任务',
checkpoints: [{ id: 'cp-1', title: '启动', status: 'running' }],
};
},
async approveCheckpoint() {
return { id: 'goal-1', checkpoints: [{ id: 'cp-1', status: 'approved' }] };
},
async pauseGoal() {
return { id: 'goal-1', status: 'paused' };
},
async resumeGoal() {
return { goal: { id: 'goal-1', status: 'active' }, checkpointId: 'cp-2' };
},
async cancelGoal() {
return { id: 'goal-1', status: 'cancelled' };
},
...overrides,
};
}
const enabledEnv = {
GOAL_RUN_ENABLED: '1',
GOAL_RUN_CANARY_USER_IDS: 'user-canary',
};
test('Goal Run routes preserve MVP inventory', () => {
const api = createRouterRecorder();
attachPortalGoalRunRoutes(api, {
getGoalRunService: () => enabledGoalRunService(),
env: enabledEnv,
});
assert.deepEqual([...api.routes.keys()], [
'POST /goals',
'GET /goals',
'GET /goals/:goalRunId',
'POST /goals/:goalRunId/checkpoints/:checkpointId/approve',
'POST /goals/:goalRunId/pause',
'POST /goals/:goalRunId/resume',
'DELETE /goals/:goalRunId',
]);
});
test('POST /goals returns 503 when service unavailable', async () => {
const api = createRouterRecorder();
attachPortalGoalRunRoutes(api, {
getGoalRunService: () => null,
env: enabledEnv,
});
const res = createResponseRecorder();
await api.routes.get('POST /goals')(
createRequest({
body: { title: '任务', intentSummary: '分阶段完成' },
}),
res,
);
assert.equal(res.statusCode, 503);
});
test('POST /goals creates goal for enabled canary user', async () => {
const api = createRouterRecorder();
attachPortalGoalRunRoutes(api, {
getGoalRunService: () => enabledGoalRunService(),
env: enabledEnv,
});
const res = createResponseRecorder();
await api.routes.get('POST /goals')(
createRequest({
body: {
title: '准备下季度产品规划',
intentSummary: '收集竞品并输出草案',
},
}),
res,
);
assert.equal(res.statusCode, 201);
assert.equal(res.body.goal.id, 'goal-1');
});
test('GET /goals rejects non-canary user', async () => {
const api = createRouterRecorder();
attachPortalGoalRunRoutes(api, {
getGoalRunService: () => enabledGoalRunService(),
env: enabledEnv,
});
const res = createResponseRecorder();
await api.routes.get('GET /goals')(
createRequest({ currentUser: { id: 'other-user' } }),
res,
);
assert.equal(res.statusCode, 403);
});
test('POST /goals/:id/resume returns checkpoint binding hint', async () => {
const api = createRouterRecorder();
attachPortalGoalRunRoutes(api, {
getGoalRunService: () => enabledGoalRunService(),
env: enabledEnv,
});
const res = createResponseRecorder();
await api.routes.get('POST /goals/:goalRunId/resume')(
createRequest({ params: { goalRunId: 'goal-1' } }),
res,
);
assert.equal(res.statusCode, 200);
assert.equal(res.body.checkpointId, 'cp-2');
});
test('POST approve auto-dispatches agent run when session_id provided', async () => {
const createdRuns = [];
const api = createRouterRecorder();
attachPortalGoalRunRoutes(api, {
getGoalRunService: () => enabledGoalRunService({
async getGoalRun({ goalRunId }) {
if (goalRunId !== 'goal-1') return null;
return {
id: 'goal-1',
title: '长期任务',
checkpoints: [
{ id: 'cp-1', title: '启动', status: 'approved' },
{ id: 'cp-2', title: '输出', status: 'pending' },
],
};
},
async startNextCheckpoint({ goalRunId }) {
return { goalRunId, checkpointId: 'cp-2' };
},
async approveCheckpoint() {
return {
id: 'goal-1',
status: 'active',
checkpoints: [{ id: 'cp-1', status: 'approved' }],
};
},
}),
getAgentRunGateway: () => ({
async createRun(userId, payload) {
createdRuns.push({ userId, payload });
return {
id: 'run-1',
userId,
sessionId: payload.sessionId,
requestId: payload.requestId,
status: 'queued',
};
},
}),
env: enabledEnv,
});
const res = createResponseRecorder();
await api.routes.get('POST /goals/:goalRunId/checkpoints/:checkpointId/approve')(
createRequest({
params: { goalRunId: 'goal-1', checkpointId: 'cp-1' },
body: { session_id: 'session-1', feedback: '继续' },
}),
res,
);
assert.equal(res.statusCode, 200);
assert.equal(res.body.goal.id, 'goal-1');
assert.equal(res.body.run.id, 'run-1');
assert.equal(createdRuns.length, 1);
assert.equal(createdRuns[0].payload.sessionId, 'session-1');
assert.equal(createdRuns[0].payload.goalRunId, 'goal-1');
});