mirror of
https://github.com/hansjone/dsh-im-ops.git
synced 2026-10-10 23:10:46 +08:00
131 lines
4.4 KiB
JavaScript
131 lines
4.4 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { VerifiedFeishuChannel } from '../../../src/channels/feishu/feishu-channel.mjs';
|
|
|
|
function fakeClient(overrides = {}) {
|
|
const calls = {
|
|
replies: [],
|
|
updates: [],
|
|
settings: [],
|
|
recalls: [],
|
|
reactionsAdded: [],
|
|
reactionsRemoved: [],
|
|
};
|
|
const client = {
|
|
cardkit: { v1: {
|
|
card: {
|
|
create: async () => ({ code: 0, data: { card_id: 'card-test' } }),
|
|
settings: async (request) => {
|
|
calls.settings.push(request);
|
|
return { code: 0 };
|
|
},
|
|
},
|
|
cardElement: {
|
|
content: async (request) => {
|
|
calls.updates.push(request);
|
|
return { code: 0 };
|
|
},
|
|
},
|
|
} },
|
|
im: { v1: {
|
|
message: {
|
|
reply: async (request) => {
|
|
calls.replies.push(request);
|
|
return { code: 0, data: { message_id: 'om-stream' } };
|
|
},
|
|
create: async () => ({ code: 0, data: { message_id: 'om-stream' } }),
|
|
delete: async (request) => {
|
|
calls.recalls.push(request);
|
|
return { code: 0 };
|
|
},
|
|
},
|
|
messageReaction: {
|
|
create: async (request) => {
|
|
calls.reactionsAdded.push(request);
|
|
return { code: 0, data: { reaction_id: 'reaction-test' } };
|
|
},
|
|
delete: async (request) => {
|
|
calls.reactionsRemoved.push(request);
|
|
return { code: 0 };
|
|
},
|
|
},
|
|
} },
|
|
};
|
|
|
|
if (overrides.updateContent) client.cardkit.v1.cardElement.content = overrides.updateContent;
|
|
if (overrides.finishCard) client.cardkit.v1.card.settings = overrides.finishCard;
|
|
return { client, calls };
|
|
}
|
|
|
|
test('VerifiedFeishuChannel streams content and verifies terminal settings', async () => {
|
|
const { client, calls } = fakeClient();
|
|
const channel = new VerifiedFeishuChannel({ client, initialText: '正在思考…' });
|
|
|
|
const result = await channel.stream('oc_chat', {
|
|
markdown: async (controller) => {
|
|
await controller.setContent('第一段');
|
|
await controller.setContent('第一段和第二段');
|
|
},
|
|
}, { replyTo: 'om_user' });
|
|
|
|
assert.deepEqual(result, { messageId: 'om-stream' });
|
|
assert.equal(calls.replies[0].path.message_id, 'om_user');
|
|
assert.deepEqual(calls.updates.map((call) => ({
|
|
content: call.data.content,
|
|
sequence: call.data.sequence,
|
|
})), [
|
|
{ content: '第一段', sequence: 1 },
|
|
{ content: '第一段和第二段', sequence: 2 },
|
|
]);
|
|
assert.equal(calls.settings[0].data.sequence, 3);
|
|
assert.deepEqual(JSON.parse(calls.settings[0].data.settings), {
|
|
config: {
|
|
streaming_mode: false,
|
|
summary: { content: '第一段和第二段' },
|
|
},
|
|
});
|
|
assert.equal(calls.recalls.length, 0);
|
|
});
|
|
|
|
test('VerifiedFeishuChannel rejects failed updates and recalls the partial card', async () => {
|
|
const { client, calls } = fakeClient({
|
|
updateContent: async () => ({ code: 230099, msg: 'element update failed' }),
|
|
});
|
|
const channel = new VerifiedFeishuChannel({ client });
|
|
|
|
await assert.rejects(channel.stream('oc_chat', {
|
|
markdown: async (controller) => controller.setContent('最终回答'),
|
|
}, { replyTo: 'om_user' }), /cardElement\.content failed/);
|
|
|
|
assert.deepEqual(calls.recalls, [{ path: { message_id: 'om-stream' } }]);
|
|
assert.equal(calls.settings.length, 0);
|
|
});
|
|
|
|
test('VerifiedFeishuChannel rejects failed finalization and recalls the card', async () => {
|
|
const { client, calls } = fakeClient({
|
|
finishCard: async (request) => {
|
|
calls.settings.push(request);
|
|
return { code: 230099, msg: 'card finalization failed' };
|
|
},
|
|
});
|
|
const channel = new VerifiedFeishuChannel({ client });
|
|
|
|
await assert.rejects(channel.stream('oc_chat', {
|
|
markdown: async (controller) => controller.setContent('已经生成的回答'),
|
|
}, { replyTo: 'om_user' }), /card\.settings failed/);
|
|
|
|
assert.deepEqual(calls.recalls, [{ path: { message_id: 'om-stream' } }]);
|
|
assert.equal(calls.settings.length, 1);
|
|
});
|
|
|
|
test('VerifiedFeishuChannel checks reaction API results', async () => {
|
|
const { client, calls } = fakeClient();
|
|
const channel = new VerifiedFeishuChannel({ client });
|
|
|
|
const reactionId = await channel.addReaction('om_user', 'OnIt');
|
|
await channel.removeReaction('om_user', reactionId);
|
|
|
|
assert.equal(reactionId, 'reaction-test');
|
|
assert.equal(calls.reactionsAdded[0].data.reaction_type.emoji_type, 'OnIt');
|
|
assert.equal(calls.reactionsRemoved[0].path.reaction_id, 'reaction-test');
|
|
});
|