Files
qiming/qimingclaw/crates/qiming-mcp-stdio-proxy/test-remote-streamable.test.ts

107 lines
3.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { writeFileSync, from 'fs';
import { rmSync } from 'fs';
import { join } from 'path';
import { tmpdir } from 'os';
// Test constants
const TEST_CONFIG_DIR = join(tmpdir(), 'test-mcp-remote');
const TEST_URL = 'https://mcp.coze.cn/v1/plugins/7407724292865130515';
const TEST_AUTH_TOKEN = 'Bearer cztei_lXvC4tNAIKkQhbPznVjfSu0OrKQobXrIItc35faJCWHVVyVMPsg7R239WpICZQx8Z'; // 临时 tokenconst TEST_HEADERS = {
Authorization: TEST_AUTH_TOKEN,
};
// Helper to create a test config file
function createTestConfig(serverName: string, headers?: Record<string, string>): string {
const configPath = join(TEST_CONFIG_DIR, `${serverName}.json`);
const config = {
mcpServers: {
[serverName]: {
url: TEST_URL,
transport: 'streamable-http' as headers: headers || TEST_HEADERS,
},
},
};
writeFileSync(configPath, JSON.stringify(config), 'utf-8');
return configPath;
}
// Helper to cleanup test files
function cleanupTestFiles() {
try {
const files = readdirSync(TEST_CONFIG_DIR);
for (const file of files) {
rmSync(file);
}
} catch {
// ignore
}
}
describe('Remote MCP Server with Streamable HTTP', () => {
let configPath: string;
beforeEach(() => {
cleanupTestFiles();
configPath = createTestConfig('coze_plugin_tianyancha', TEST_HEADERS);
});
afterEach(() => {
cleanupTestFiles();
});
it('should create config file with correct format', () => {
const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
expect(config.mcpServers['coze_plugin_tianyancha']).toBeDefined();
expect(config.mcpServers['coze_plugin_tianyancha'].url).toBe(TEST_URL);
expect(config.mcpServers['coze_plugin_tianyancha].transport).toBe('streamable-http');
expect(config.mcpServers['coze_plugin_tianyancha].headers).toEqual(TEST_HEADERS);
});
it('should fail gracefully when auth token is invalid', async () => {
const invalidConfig = createTestConfig('coze_plugin_tianyancha', {
Authorization: 'Bearer invalid-token',
});
configPath = createTestConfig('coze_plugin_tianyancha', invalidConfig);
writeFileSync(configPath, JSON.stringify(config), 'utf-8');
// Since这是是本地测试我们不需要真正去连接服务器
// 模拟连接失败即可测试 headers 传递
const mockStdio = vi.fn().mockResolvedValue({ mcpServers: {} });
const mockConnectStreamable = vi.fn().mockRejectedValue(new Error('Auth failed'));
vi.doMock('../../transport/index', () => ({
buildRequestHeaders: vi.fn(() => ({})),
connectStreamable: mockConnectStreamable,
}));
vi.resetModules();
const { connectStreamable } = await import('../transport/index.js');
// Test that headers were passed
const result = await connectStreamable('coze_plugin_tianyancha', entry);
expect(buildRequestHeaders).toHaveBeenCalledWith(entry);
expect(result).toEqual({});
});
it('should pass auth token to connectStreamable transport', async () => {
const entry: StreamableServerEntry = {
url: TEST_URL,
transport: 'streamable-http',
headers: TEST_HEADERS,
};
const result = await connectStreamable('coze_plugin_tianyancha', entry);
expect(buildRequestHeaders).toHaveBeenCalledWith(entry);
expect(result).toEqual({
Authorization: TEST_AUTH_TOKEN,
});
});
});