mirror of
https://github.com/hansjone/dsh-im-ops.git
synced 2026-10-13 00:10:47 +08:00
feat: add message source context enhancement
This commit is contained in:
parent
5928b33057
commit
0cb79f74e9
69 changed files with 6217 additions and 597 deletions
|
|
@ -226,6 +226,84 @@ test('runtime sends visible-scope messages to Harness without local sender appro
|
|||
await runtime.stop();
|
||||
});
|
||||
|
||||
for (const scenario of [
|
||||
{ name: 'private enabled to disabled', conversationType: '1', before: [true, false], after: [false, true] },
|
||||
{ name: 'group enabled to disabled', conversationType: '2', before: [false, true], after: [true, false] },
|
||||
{ name: 'private disabled to enabled', conversationType: '1', before: [false, true], after: [true, false] },
|
||||
]) {
|
||||
test(`DingTalk received callback retains settings before its parse microtask: ${scenario.name}`, async () => {
|
||||
const order = [];
|
||||
const asked = [];
|
||||
const configFor = ([directEnabled, groupEnabled], guidance) => ({
|
||||
directEnabled, groupEnabled, fields: ['channel', 'botId'], guidance,
|
||||
});
|
||||
let config = configFor(scenario.before, 'before callback returned');
|
||||
let callback;
|
||||
const client = {
|
||||
connected: true,
|
||||
socket: { readyState: 1 },
|
||||
registerCallbackListener(_topic, listener) { callback = listener; },
|
||||
async connect() {},
|
||||
socketCallBackResponse(messageId) { order.push(['ack', messageId]); },
|
||||
disconnect() {},
|
||||
};
|
||||
const runtime = new DingtalkRuntime({
|
||||
config: { clientId: 'ding-client', approvedSenders: [] },
|
||||
clientSecret: 'host-secret',
|
||||
contextEnhancement: {
|
||||
botId: 'dingtalk_internal',
|
||||
getSettings: () => { order.push(['settings']); return config; },
|
||||
},
|
||||
harness: {
|
||||
ensureRunning: async () => true,
|
||||
createSession: async () => 'session-existing',
|
||||
sessionExists: async () => true,
|
||||
ask: async (_sessionId, text) => { asked.push(text); order.push(['ask']); return 'done'; },
|
||||
},
|
||||
state: stateFixture(),
|
||||
api: { sendText: async () => {} },
|
||||
streamFactory: async () => ({ client, topic: 'robot-topic' }),
|
||||
logger: { warn() {}, error() {} },
|
||||
});
|
||||
const response = (id) => ({
|
||||
headers: { messageId: `callback-${id}` },
|
||||
get data() {
|
||||
order.push(['read-data', id]);
|
||||
return JSON.stringify({
|
||||
msgId: `message-${id}`, msgtype: 'text', text: { content: `message ${id}` },
|
||||
conversationType: scenario.conversationType, conversationId: 'group-chat',
|
||||
isInAtList: true, senderStaffId: 'staff-id', senderNick: 'Ada',
|
||||
sessionWebhook: 'https://oapi.dingtalk.com/robot/reply?ticket=test',
|
||||
});
|
||||
},
|
||||
});
|
||||
try {
|
||||
await runtime.start();
|
||||
callback(response(1));
|
||||
assert.deepEqual(order, [['ack', 'callback-1'], ['settings']], 'ACK stays first and JSON remains unparsed until the original microtask');
|
||||
config = configFor(scenario.after, 'after callback returned');
|
||||
await eventually(() => runtime.status.messagesReplied === 1, 5_000);
|
||||
callback(response(2));
|
||||
await eventually(() => runtime.status.messagesReplied === 2, 5_000);
|
||||
for (const [index, switches] of [scenario.before, scenario.after].entries()) {
|
||||
const enabled = switches[scenario.conversationType === '1' ? 0 : 1];
|
||||
if (enabled) {
|
||||
assert.match(asked[index], index === 0 ? /before callback returned/ : /after callback returned/);
|
||||
assert.deepEqual(JSON.parse(/^<dsh_im_source>(.*?)<\/dsh_im_source>/su.exec(asked[index])[1]), {
|
||||
channel: 'dingtalk', botId: 'dingtalk_internal',
|
||||
});
|
||||
} else {
|
||||
assert.equal(asked[index], `message ${index + 1}`);
|
||||
}
|
||||
}
|
||||
assert.equal(order.filter(([action]) => action === 'settings').length, 2, 'one source configuration read per callback');
|
||||
assert.equal(order.filter(([action]) => action === 'read-data').length, 4, 'preserves the original data parsing path');
|
||||
} finally {
|
||||
await runtime.stop();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
test('runtime accepts an OPEN DingTalk socket when the SDK registered flag remains false', async () => {
|
||||
const client = {
|
||||
connected: true,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue