Files
memind/wechat/ack/ack-provider.test.mjs
john 9b4a25799f Add smart ACK provider for WeChat MP replies
Replace fixed ackText with a rule-based AckProvider that picks
response templates by message type and intent (translate, summary,
rewrite, poster, ppt, mindmap, code, search, schedule). Pure sync,
zero I/O, auto-falls back to config.ackText on any error.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-26 15:19:03 +08:00

94 lines
4.2 KiB
JavaScript

import { describe, it } from 'node:test';
import assert from 'node:assert/strict';
import { buildAckText } from './ack-provider.mjs';
const cfg = { ackRandomEnabled: false, ackNicknameEnabled: false, ackText: '已收到,正在处理,完成后发到这里。' };
const cfgNick = { ...cfg, ackNicknameEnabled: true };
function intent(msgType, agentText = '') {
return { msgType, agentText };
}
describe('buildAckText', () => {
it('returns fallback when config throws', () => {
const badConfig = { get ackRandomEnabled() { throw new Error('bad'); } };
const result = buildAckText({ intent: intent('text', '你好'), nickname: '', config: badConfig, fallbackText: '兜底' });
assert.equal(result, '兜底');
});
it('null intent falls through to default template gracefully', () => {
const result = buildAckText({ intent: null, nickname: '', config: cfg, fallbackText: '兜底' });
assert.equal(result, '收到,我马上处理。');
});
it('image → image template', () => {
const result = buildAckText({ intent: intent('image'), nickname: '', config: cfg, fallbackText: '' });
assert.equal(result, '图片收到,我先看看。');
});
it('voice → voice template', () => {
const result = buildAckText({ intent: intent('voice'), nickname: '', config: cfg, fallbackText: '' });
assert.equal(result, '收到语音,我先听一下。');
});
it('location → location template', () => {
const result = buildAckText({ intent: intent('location'), nickname: '', config: cfg, fallbackText: '' });
assert.equal(result, '收到位置,我来看看。');
});
it('link → link template', () => {
const result = buildAckText({ intent: intent('link'), nickname: '', config: cfg, fallbackText: '' });
assert.equal(result, '收到链接,我去读一下。');
});
it('text with translate intent', () => {
const result = buildAckText({ intent: intent('text', '帮我翻译一段文字'), nickname: '', config: cfg, fallbackText: '' });
assert.equal(result, '收到,我开始翻译。');
});
it('text with summary intent', () => {
const result = buildAckText({ intent: intent('text', '帮我总结一下这篇文章'), nickname: '', config: cfg, fallbackText: '' });
assert.equal(result, '收到,我开始整理重点。');
});
it('text with rewrite intent', () => {
const result = buildAckText({ intent: intent('text', '帮我写一篇文章'), nickname: '', config: cfg, fallbackText: '' });
assert.equal(result, '收到,我开始写。');
});
it('text with ppt intent', () => {
const result = buildAckText({ intent: intent('text', '帮我做个PPT'), nickname: '', config: cfg, fallbackText: '' });
assert.equal(result, '收到,我开始制作 PPT。');
});
it('text with mindmap intent', () => {
const result = buildAckText({ intent: intent('text', '帮我画个思维导图'), nickname: '', config: cfg, fallbackText: '' });
assert.equal(result, '收到,我来整理思维导图。');
});
it('text with code intent', () => {
const result = buildAckText({ intent: intent('text', '帮我看看这段代码'), nickname: '', config: cfg, fallbackText: '' });
assert.equal(result, '收到,我来看看代码。');
});
it('unknown text → default template', () => {
const result = buildAckText({ intent: intent('text', '随便说点什么'), nickname: '', config: cfg, fallbackText: '' });
assert.equal(result, '收到,我马上处理。');
});
it('nickname prepended when enabled', () => {
const result = buildAckText({ intent: intent('text', '随便'), nickname: '小明', config: cfgNick, fallbackText: '' });
assert.equal(result, '小明,收到,我马上处理。');
});
it('no nickname prefix when nickname is empty', () => {
const result = buildAckText({ intent: intent('text', '随便'), nickname: '', config: cfgNick, fallbackText: '' });
assert.equal(result, '收到,我马上处理。');
});
it('voice with agentText still uses voice template (msgType wins)', () => {
const result = buildAckText({ intent: intent('voice', '帮我翻译一下'), nickname: '', config: cfg, fallbackText: '' });
assert.equal(result, '收到语音,我先听一下。');
});
});