Files
memind/page-data-delivery-code-review.test.mjs
john 8bfb7959fc
Memind CI / Test, build, and release guards (push) Has been cancelled
fix: guard WeChat Page Data delivery with Aider review
2026-07-28 00:26:24 +08:00

254 lines
7.6 KiB
JavaScript

import assert from 'node:assert/strict';
import fs from 'node:fs/promises';
import os from 'node:os';
import path from 'node:path';
import test from 'node:test';
import {
createPageDataDeliveryCodeReviewService,
inspectPageDataHtmlScripts,
} from './page-data-delivery-code-review.mjs';
const VALID_PAGE = `<!doctype html>
<script src="/assets/page-data-client.js"></script>
<script>
const client = MindSpacePageData.createClient({ apiBase: '/api' });
async function loadRows() {
return client.listRows('checkin_records', { limit: 50 });
}
</script>`;
const BROKEN_PAGE = `<!doctype html>
<script src="/assets/page-data-client.js"></script>
<script>
async function tryAuth() {
try {
await client.authenticate('888');
} catch (error) {
console.error(error);
}
loadRows();
})();
</script>`;
async function createWorkspace(html = VALID_PAGE) {
const root = await fs.mkdtemp(path.join(os.tmpdir(), 'page-data-code-review-'));
await fs.mkdir(path.join(root, 'public'), { recursive: true });
await fs.writeFile(path.join(root, 'public', 'checkin.html'), html);
return root;
}
function createGateway(workspace, {
executor = 'aider',
receiptStatus = 'passed',
fixHtml = null,
removeHtml = false,
} = {}) {
const jobs = [];
return {
jobs,
getStatus() {
return {
enabled: true,
executors: ['aider', 'openhands'],
};
},
async executeJob(job) {
jobs.push(job);
if (fixHtml) {
await fs.writeFile(path.join(workspace, 'public', 'checkin.html'), fixHtml);
}
if (removeHtml) {
await fs.rm(path.join(workspace, 'public', 'checkin.html'));
}
const receiptPath = job.userMessage.metadata.memindRun.aiderContextFiles
.find((item) => item.startsWith('.memind/page-data-reviews/'));
await fs.writeFile(
path.join(workspace, receiptPath),
JSON.stringify({
requestId: job.requestId,
sourceChannel: 'wechat_mp',
executor: 'aider',
status: receiptStatus,
reviewedFiles: ['public/checkin.html'],
issues: fixHtml ? ['fixed_javascript_syntax'] : [],
}),
);
return {
ok: true,
executor,
exitCode: 0,
cwd: workspace,
};
},
};
}
test('inline Page Data syntax inspection catches the broken check-in script', () => {
const failures = inspectPageDataHtmlScripts(BROKEN_PAGE, {
relativePath: 'public/checkin.html',
});
assert.equal(failures.length, 1);
assert.match(failures[0].message, /Unexpected token/);
assert.equal(inspectPageDataHtmlScripts(VALID_PAGE).length, 0);
});
test('Page Data delivery review skips ordinary static HTML', async (t) => {
const workspace = await createWorkspace('<!doctype html><h1>Static page</h1>');
t.after(() => fs.rm(workspace, { recursive: true, force: true }));
const gateway = createGateway(workspace);
const service = createPageDataDeliveryCodeReviewService({
toolGateway: gateway,
userAuth: {
async resolveWorkingDir() {
return workspace;
},
},
});
const result = await service.reviewIfNeeded({
sourceChannel: 'wechat_mp',
userId: 'user-1',
requestId: 'request-static',
relativePaths: ['public/checkin.html'],
});
assert.deepEqual(result, { action: 'skip', reason: 'not_page_data' });
assert.equal(gateway.jobs.length, 0);
});
test('Page Data delivery review requires Aider receipt and final syntax pass', async (t) => {
const workspace = await createWorkspace(BROKEN_PAGE);
t.after(() => fs.rm(workspace, { recursive: true, force: true }));
const gateway = createGateway(workspace, { fixHtml: VALID_PAGE });
const service = createPageDataDeliveryCodeReviewService({
toolGateway: gateway,
userAuth: {
async resolveWorkingDir() {
return workspace;
},
},
});
const result = await service.reviewIfNeeded({
sourceChannel: 'wechat_mp',
userId: 'user-1',
requestId: 'request-broken-page',
sessionId: 'session-1',
sourceMessageId: 'wx-message-1',
originalUserText: '打卡页面提交失败,请修复',
relativePaths: ['public/checkin.html'],
forcePageData: true,
});
assert.equal(result.action, 'passed');
assert.equal(result.executor, 'aider');
assert.deepEqual(result.reviewedFiles, ['public/checkin.html']);
assert.equal(gateway.jobs.length, 1);
assert.equal(gateway.jobs[0].taskType, 'page_data_dev');
assert.match(gateway.jobs[0].userMessage.content[0].text, /Initial JavaScript syntax failures/);
assert.match(gateway.jobs[0].userMessage.content[0].text, /untrusted input/);
});
test('Page Data delivery review fails closed on executor mismatch', async (t) => {
const workspace = await createWorkspace();
t.after(() => fs.rm(workspace, { recursive: true, force: true }));
const gateway = createGateway(workspace, { executor: 'openhands' });
const service = createPageDataDeliveryCodeReviewService({
toolGateway: gateway,
userAuth: {
async resolveWorkingDir() {
return workspace;
},
},
});
await assert.rejects(
service.reviewIfNeeded({
sourceChannel: 'wechat_mp',
userId: 'user-1',
requestId: 'request-wrong-executor',
relativePaths: ['public/checkin.html'],
forcePageData: true,
}),
(error) => error?.code === 'PAGE_DATA_REVIEW_EXECUTOR_MISMATCH',
);
});
test('Page Data delivery review fails closed when Aider leaves a pending receipt', async (t) => {
const workspace = await createWorkspace();
t.after(() => fs.rm(workspace, { recursive: true, force: true }));
const gateway = createGateway(workspace, { receiptStatus: 'pending' });
const service = createPageDataDeliveryCodeReviewService({
toolGateway: gateway,
userAuth: {
async resolveWorkingDir() {
return workspace;
},
},
});
await assert.rejects(
service.reviewIfNeeded({
sourceChannel: 'wechat_mp',
userId: 'user-1',
requestId: 'request-pending',
relativePaths: ['public/checkin.html'],
forcePageData: true,
}),
(error) => error?.code === 'PAGE_DATA_REVIEW_NOT_PASSED',
);
});
test('Page Data delivery review fails closed when Aider removes the reviewed artifact', async (t) => {
const workspace = await createWorkspace();
t.after(() => fs.rm(workspace, { recursive: true, force: true }));
const gateway = createGateway(workspace, { removeHtml: true });
const service = createPageDataDeliveryCodeReviewService({
toolGateway: gateway,
userAuth: {
async resolveWorkingDir() {
return workspace;
},
},
});
await assert.rejects(
service.reviewIfNeeded({
sourceChannel: 'wechat_mp',
userId: 'user-1',
requestId: 'request-removed',
relativePaths: ['public/checkin.html'],
forcePageData: true,
}),
(error) => error?.code === 'PAGE_DATA_REVIEW_ARTIFACT_MISSING',
);
});
test('Page Data delivery review rejects removal of the Page Data client contract', async (t) => {
const workspace = await createWorkspace();
t.after(() => fs.rm(workspace, { recursive: true, force: true }));
const gateway = createGateway(workspace, {
fixHtml: '<!doctype html><script>console.log("static")</script>',
});
const service = createPageDataDeliveryCodeReviewService({
toolGateway: gateway,
userAuth: {
async resolveWorkingDir() {
return workspace;
},
},
});
await assert.rejects(
service.reviewIfNeeded({
sourceChannel: 'wechat_mp',
userId: 'user-1',
requestId: 'request-contract-removed',
relativePaths: ['public/checkin.html'],
forcePageData: true,
}),
(error) => error?.code === 'PAGE_DATA_REVIEW_CONTRACT_REMOVED',
);
});