@kedoupi/wecombot-mcp
Version:
A Model Context Protocol (MCP) server for WeChat Work (企业微信) group bot integration
159 lines • 6.87 kB
JavaScript
import { describe, it, beforeEach, afterEach } from 'node:test';
import assert from 'node:assert';
import nock from 'nock';
import { WeComClient } from '../wecom-client.js';
describe('WeComClient', () => {
let client;
const mockWebhookUrl = 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=test-key';
beforeEach(() => {
client = new WeComClient(mockWebhookUrl);
nock.cleanAll();
});
afterEach(() => {
nock.cleanAll();
});
describe('sendMessage', () => {
it('should send text message successfully', async () => {
const scope = nock('https://qyapi.weixin.qq.com')
.post('/cgi-bin/webhook/send', {
msgtype: 'text',
text: {
content: 'Hello, World!',
},
})
.query({ key: 'test-key' })
.reply(200, { errcode: 0, errmsg: 'ok' });
const result = await client.sendMessage({
message_type: 'text',
content: 'Hello, World!',
});
assert.strictEqual(result.success, true);
assert.strictEqual(scope.isDone(), true);
});
it('should send text message with mentions', async () => {
const scope = nock('https://qyapi.weixin.qq.com')
.post('/cgi-bin/webhook/send', {
msgtype: 'text',
text: {
content: 'Hello everyone!',
mentioned_list: ['@all'],
},
})
.query({ key: 'test-key' })
.reply(200, { errcode: 0, errmsg: 'ok' });
const result = await client.sendMessage({
message_type: 'text',
content: 'Hello everyone!',
mentioned_list: ['@all'],
});
assert.strictEqual(result.success, true);
assert.strictEqual(scope.isDone(), true);
});
it('should send markdown message successfully', async () => {
const markdownContent = '# Title\n**Bold text**';
const scope = nock('https://qyapi.weixin.qq.com')
.post('/cgi-bin/webhook/send', {
msgtype: 'markdown',
markdown: {
content: markdownContent,
},
})
.query({ key: 'test-key' })
.reply(200, { errcode: 0, errmsg: 'ok' });
const result = await client.sendMessage({
message_type: 'markdown',
content: markdownContent,
});
assert.strictEqual(result.success, true);
assert.strictEqual(scope.isDone(), true);
});
it('should send image message with correct md5', async () => {
const base64Image = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8/5+hHgAHggJ/PchI7wAAAABJRU5ErkJggg==';
const scope = nock('https://qyapi.weixin.qq.com')
.post('/cgi-bin/webhook/send', (body) => {
return body.msgtype === 'image' &&
body.image.base64 === base64Image &&
typeof body.image.md5 === 'string' &&
body.image.md5.length === 32;
})
.query({ key: 'test-key' })
.reply(200, { errcode: 0, errmsg: 'ok' });
const result = await client.sendMessage({
message_type: 'image',
content: base64Image,
});
assert.strictEqual(result.success, true);
assert.strictEqual(scope.isDone(), true);
});
it('should send news message successfully', async () => {
const scope = nock('https://qyapi.weixin.qq.com')
.post('/cgi-bin/webhook/send', {
msgtype: 'news',
news: {
articles: [{
title: 'Test Article',
description: 'Article content',
url: 'https://example.com',
picurl: 'https://example.com/pic.jpg',
}],
},
})
.query({ key: 'test-key' })
.reply(200, { errcode: 0, errmsg: 'ok' });
const result = await client.sendMessage({
message_type: 'news',
content: 'Article content',
title: 'Test Article',
url: 'https://example.com',
description: 'Article content',
picurl: 'https://example.com/pic.jpg',
});
assert.strictEqual(result.success, true);
assert.strictEqual(scope.isDone(), true);
});
it('should handle WeChat API error', async () => {
const scope = nock('https://qyapi.weixin.qq.com')
.post('/cgi-bin/webhook/send')
.query({ key: 'test-key' })
.reply(200, { errcode: 93000, errmsg: 'invalid webhook url' });
const result = await client.sendMessage({
message_type: 'text',
content: 'Test message',
});
assert.strictEqual(result.success, false);
assert.ok(result.message?.includes('invalid webhook url'));
assert.strictEqual(scope.isDone(), true);
});
it('should handle network error', async () => {
const scope = nock('https://qyapi.weixin.qq.com')
.post('/cgi-bin/webhook/send')
.query({ key: 'test-key' })
.replyWithError('Network error');
const result = await client.sendMessage({
message_type: 'text',
content: 'Test message',
});
assert.strictEqual(result.success, false);
assert.ok(result.message?.includes('HTTP error'));
assert.strictEqual(scope.isDone(), true);
});
it('should validate news message parameters', async () => {
const result = await client.sendMessage({
message_type: 'news',
content: 'Article content',
// Missing required title and url
});
assert.strictEqual(result.success, false);
assert.ok(result.message?.includes('News message requires title and url'));
});
it('should handle unsupported message type', async () => {
const result = await client.sendMessage({
message_type: 'unsupported',
content: 'Test content',
});
assert.strictEqual(result.success, false);
assert.ok(result.message?.includes('Unsupported message type'));
});
});
});
//# sourceMappingURL=wecom-client.test.js.map