dsh-im-ops/test/channels/qq/bridge.test.mjs
2026-08-15 17:51:48 +08:00

81 lines
2.5 KiB
JavaScript

import assert from 'node:assert/strict';
import test from 'node:test';
import { QqHarnessBridge } from '../../../src/channels/qq/qq-bridge.mjs';
function message(overrides = {}) {
return {
kind: 'c2c',
rawEventType: 'C2C_MESSAGE_CREATE',
senderId: 'owner-openid',
senderIsBot: false,
content: '请回答',
messageId: 'msg-1',
replyTarget: { scope: 'c2c', targetId: 'owner-openid', msgId: 'msg-1' },
...overrides,
};
}
test('QQ private messages stream Harness snapshots and finalize once', async () => {
const frames = [];
const sent = [];
const seen = new Set();
const bridge = new QqHarnessBridge({
bot: {
sendText: async (_target, text) => sent.push(text),
openStream: () => ({
update: async (text) => frames.push(text),
complete: async () => frames.push('DONE'),
cancel() {},
}),
},
ownerUserOpenid: 'owner-openid',
harness: {
sessionExists: async () => true,
createSession: async () => 'session-new',
ensureRunning: async () => true,
ask: async (_session, _text, { onUpdate }) => {
await onUpdate({ type: 'text', text: '回答中' });
return '最终回答';
},
},
state: {
hasSeen: (id) => seen.has(id),
markSeen: async (id) => seen.add(id),
sessionFor: () => 'session-existing',
setSession: async () => {},
clearSession: async () => {},
},
});
await bridge.accept(message());
assert.deepEqual(frames, ['回答中', '最终回答', 'DONE']);
assert.deepEqual(sent, []);
assert.equal(seen.has('msg-1'), true);
assert.equal(bridge.status.messagesReplied, 1);
});
test('QQ bridge accepts only the scanner and requires an at-message event in groups', async () => {
let asks = 0;
const state = {
hasSeen: () => false,
markSeen: async () => {},
sessionFor: () => 'session',
sessionExists: async () => true,
setSession: async () => {},
clearSession: async () => {},
};
const bridge = new QqHarnessBridge({
bot: { sendText: async () => {} },
ownerUserOpenid: 'owner-openid',
harness: { sessionExists: async () => true, ask: async () => { asks += 1; return 'ok'; } },
state,
});
await bridge.accept(message({ messageId: 'other', senderId: 'other-openid' }));
await bridge.accept(message({
messageId: 'group', kind: 'group', groupOpenid: 'group-1', rawEventType: 'GROUP_MESSAGE_CREATE',
replyTarget: { scope: 'group', targetId: 'group-1', msgId: 'group' },
}));
assert.equal(asks, 0);
assert.equal(bridge.status.messagesRejected, 1);
});