Files
memind/agent-run-deliverable-check.test.mjs

78 lines
2.9 KiB
JavaScript

import test from 'node:test';
import assert from 'node:assert/strict';
import {
detectSessionDeliverables,
hasRecoverableSessionDeliverables,
isRecoverableFinishError,
tryRecoverRunFromSessionDeliverables,
} from './agent-run-deliverable-check.mjs';
test('isRecoverableFinishError recognizes finish and run timeout codes', () => {
assert.equal(isRecoverableFinishError({ code: 'SESSION_REPLY_INCOMPLETE' }), true);
assert.equal(isRecoverableFinishError({ code: 'SESSION_REPLY_TIMEOUT' }), true);
assert.equal(isRecoverableFinishError({ code: 'AGENT_RUN_TIMEOUT' }), true);
assert.equal(isRecoverableFinishError({ code: 'TOOL_GATEWAY_VALIDATION_FAILED' }), false);
});
test('detectSessionDeliverables counts pages and online publications for a session', async () => {
const pool = {
async query(sql, params) {
assert.match(sql, /source_session_id/);
assert.deepEqual(params, ['user-1', 'session-1']);
return [[
{
page_id: 'page-front',
title: '前台',
publication_id: 'pub-front',
publication_status: 'online',
public_url: 'https://example.com/u/john/pages/page-front',
},
{
page_id: 'page-admin',
title: '后台',
publication_id: null,
publication_status: null,
public_url: null,
},
]];
},
};
const summary = await detectSessionDeliverables(pool, 'user-1', 'session-1');
assert.equal(summary.pageCount, 2);
assert.equal(summary.publicationCount, 1);
assert.equal(summary.pages[0].publicUrl, 'https://example.com/u/john/pages/page-front');
});
test('tryRecoverRunFromSessionDeliverables succeeds when pages exist despite finish timeout', async () => {
const pool = {
async query() {
return [[{ page_id: 'page-1', title: 'Survey', publication_id: 'pub-1', public_url: '/u/j/x' }]];
},
};
const recovered = await tryRecoverRunFromSessionDeliverables({
pool,
userId: 'user-1',
sessionId: 'session-1',
error: Object.assign(new Error('session reply timed out'), { code: 'SESSION_REPLY_TIMEOUT' }),
});
assert.ok(recovered);
assert.equal(recovered.deliverables.pageCount, 1);
assert.equal(recovered.originalError.code, 'SESSION_REPLY_TIMEOUT');
});
test('tryRecoverRunFromSessionDeliverables returns null when no deliverables exist', async () => {
const pool = { async query() { return [[]]; } };
const recovered = await tryRecoverRunFromSessionDeliverables({
pool,
userId: 'user-1',
sessionId: 'session-1',
error: Object.assign(new Error('stream ended'), { code: 'SESSION_REPLY_INCOMPLETE' }),
});
assert.equal(recovered, null);
});
test('hasRecoverableSessionDeliverables accepts pages even without online publication', () => {
assert.equal(hasRecoverableSessionDeliverables({ pageCount: 1, publicationCount: 0 }), true);
assert.equal(hasRecoverableSessionDeliverables({ pageCount: 0, publicationCount: 0 }), false);
});