@kedoupi/wecombot-mcp
Version:
A Model Context Protocol (MCP) server for WeChat Work (企业微信) group bot integration
158 lines • 6.65 kB
JavaScript
import { describe, it, beforeEach, afterEach } from 'node:test';
import assert from 'node:assert';
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
import nock from 'nock';
describe('MCP Server Integration', () => {
let server;
const originalEnv = process.env.WECOM_WEBHOOK_URL;
beforeEach(() => {
process.env.WECOM_WEBHOOK_URL = 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=test-key';
server = new Server({
name: 'wecombot-mcp',
version: '1.0.0',
}, {
capabilities: {
tools: {},
},
});
// Setup handlers (simplified version of the actual server)
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
{
name: 'send_wecom_message',
description: 'Send message to WeChat Work group via webhook',
inputSchema: {
type: 'object',
properties: {
message_type: {
type: 'string',
enum: ['text', 'markdown', 'image', 'news'],
description: 'Type of message to send',
},
content: {
type: 'string',
description: 'Message content (text/markdown) or base64 image data',
},
mentioned_list: {
type: 'array',
items: { type: 'string' },
description: 'List of users to mention (@all for everyone)',
},
},
required: ['message_type', 'content'],
},
},
],
};
});
nock.cleanAll();
});
afterEach(() => {
process.env.WECOM_WEBHOOK_URL = originalEnv;
nock.cleanAll();
});
describe('ListTools', () => {
it('should return available tools', async () => {
const result = await server.request({ method: 'tools/list' }, ListToolsRequestSchema);
assert.strictEqual(result.tools.length, 1);
assert.strictEqual(result.tools[0].name, 'send_wecom_message');
assert.ok(result.tools[0].description.includes('WeChat Work'));
// Validate schema structure
const schema = result.tools[0].inputSchema;
assert.strictEqual(schema.type, 'object');
assert.ok(schema.properties);
assert.ok(schema.properties.message_type);
assert.ok(schema.properties.content);
assert.deepStrictEqual(schema.required, ['message_type', 'content']);
});
});
describe('Tool Parameter Validation', () => {
it('should validate message_type enum values', () => {
const schema = {
type: 'object',
properties: {
message_type: {
type: 'string',
enum: ['text', 'markdown', 'image', 'news'],
},
content: {
type: 'string',
},
},
required: ['message_type', 'content'],
};
// Test valid enum values
const validTypes = ['text', 'markdown', 'image', 'news'];
validTypes.forEach(type => {
assert.ok(schema.properties.message_type.enum.includes(type));
});
// Verify enum length
assert.strictEqual(schema.properties.message_type.enum.length, 4);
});
it('should have correct required fields', () => {
const schema = {
type: 'object',
properties: {
message_type: { type: 'string' },
content: { type: 'string' },
mentioned_list: { type: 'array' },
},
required: ['message_type', 'content'],
};
assert.deepStrictEqual(schema.required, ['message_type', 'content']);
assert.strictEqual(schema.required.length, 2);
});
});
describe('Error Handling', () => {
it('should handle missing environment variable', async () => {
delete process.env.WECOM_WEBHOOK_URL;
try {
// This would be handled in the actual CallTool handler
const webhookUrl = process.env.WECOM_WEBHOOK_URL;
if (!webhookUrl) {
throw new Error('WECOM_WEBHOOK_URL environment variable is required');
}
assert.fail('Should have thrown an error');
}
catch (error) {
assert.ok(error instanceof Error);
assert.ok(error.message.includes('WECOM_WEBHOOK_URL'));
}
});
it('should validate webhook URL format', () => {
const validUrl = 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=test-key';
const invalidUrls = [
'http://example.com',
'not-a-url',
'https://wrong-domain.com/webhook',
'',
];
// Test valid URL
assert.ok(validUrl.startsWith('https://qyapi.weixin.qq.com'));
// Test invalid URLs
invalidUrls.forEach(url => {
assert.ok(!url.startsWith('https://qyapi.weixin.qq.com'));
});
});
});
describe('MCP Protocol Compliance', () => {
it('should use correct MCP server metadata', () => {
const serverInfo = {
name: 'wecombot-mcp',
version: '1.0.0',
};
assert.strictEqual(serverInfo.name, 'wecombot-mcp');
assert.match(serverInfo.version, /^\d+\.\d+\.\d+$/);
});
it('should declare correct capabilities', () => {
const capabilities = {
tools: {},
};
assert.ok(capabilities.tools !== undefined);
assert.strictEqual(typeof capabilities.tools, 'object');
});
});
});
//# sourceMappingURL=mcp-server.test.js.map