feat(wechat): channel split with stub-safe page delivery
Introduce wechat/ channel package; never send stub HTML links to service-account users.
This commit was merged in pull request #2.
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import fs from 'node:fs';
|
||||
import os from 'node:os';
|
||||
import path from 'node:path';
|
||||
import test from 'node:test';
|
||||
import { classifyWechatIntent, isPageGenerateIntent } from './intent/classifier.mjs';
|
||||
import {
|
||||
filterSendableHtmlArtifacts,
|
||||
isStubPublicHtmlContent,
|
||||
selectSendableHtmlArtifacts,
|
||||
verifyPageArtifactContent,
|
||||
} from './verify/page-artifact.mjs';
|
||||
import { resolvePageGenerateOutcome } from './handlers/page-generate.mjs';
|
||||
|
||||
test('classifyWechatIntent detects page.generate', () => {
|
||||
const intent = classifyWechatIntent({
|
||||
msgType: 'text',
|
||||
agentText: '帮我生成一个唐诗页面,放一首诗',
|
||||
});
|
||||
assert.equal(intent.kind, 'page.generate');
|
||||
assert.match(intent.topic, /唐诗页面/);
|
||||
assert.equal(isPageGenerateIntent({ msgType: 'text', agentText: intent.topic }), true);
|
||||
});
|
||||
|
||||
test('classifyWechatIntent detects session.reset', () => {
|
||||
assert.equal(classifyWechatIntent({ msgType: 'text', agentText: '换话题' }).kind, 'session.reset');
|
||||
});
|
||||
|
||||
test('selectSendableHtmlArtifacts never returns stub html', () => {
|
||||
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'wechat-stub-'));
|
||||
const stubPath = path.join(dir, 'tang-poem.html');
|
||||
fs.writeFileSync(
|
||||
stubPath,
|
||||
'<html>服务号自动补出简版页面</html>',
|
||||
'utf8',
|
||||
);
|
||||
const realPath = path.join(dir, 'real.html');
|
||||
fs.writeFileSync(
|
||||
realPath,
|
||||
`<!doctype html><html><body><main>${'x'.repeat(600)}</main></body></html>`,
|
||||
'utf8',
|
||||
);
|
||||
const artifacts = [
|
||||
{ localPath: stubPath, relativePath: 'public/tang-poem.html', url: 'https://example/tang-poem.html' },
|
||||
{ localPath: realPath, relativePath: 'public/real.html', url: 'https://example/real.html' },
|
||||
];
|
||||
const sendable = selectSendableHtmlArtifacts({ confirmedArtifacts: artifacts });
|
||||
assert.equal(sendable.length, 1);
|
||||
assert.match(sendable[0].relativePath, /real\.html/);
|
||||
assert.equal(isStubPublicHtmlContent('<html>服务号自动补出简版页面</html>'), true);
|
||||
});
|
||||
|
||||
test('resolvePageGenerateOutcome fails when only stub artifacts exist', () => {
|
||||
const outcome = resolvePageGenerateOutcome({
|
||||
reply: { text: '页面已生成 https://m.tkmind.cn/MindSpace/u/public/tang-poem.html' },
|
||||
confirmedArtifacts: [
|
||||
{
|
||||
localPath: '/tmp/stub.html',
|
||||
relativePath: 'public/tang-poem.html',
|
||||
},
|
||||
],
|
||||
htmlGenerationNeedsRetry: true,
|
||||
replyHasPublicLinks: true,
|
||||
});
|
||||
assert.equal(outcome.action, 'fail');
|
||||
assert.match(outcome.failureText, /服务号页面技能/);
|
||||
});
|
||||
|
||||
test('verifyPageArtifactContent rejects small stub files', () => {
|
||||
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'wechat-verify-'));
|
||||
const file = path.join(dir, 'page.html');
|
||||
fs.writeFileSync(file, '<html>服务号兜底</html>', 'utf8');
|
||||
const artifact = { localPath: file, relativePath: 'public/page.html' };
|
||||
assert.equal(verifyPageArtifactContent(artifact).ok, false);
|
||||
assert.equal(filterSendableHtmlArtifacts([artifact]).length, 0);
|
||||
});
|
||||
Reference in New Issue
Block a user