UNPKG

@qwe8652591/prompt-ai

Version:

DPML-powered AI prompt framework - Revolutionary AI-First CLI system based on Deepractice Prompt Markup Language. Build sophisticated AI agents with structured prompts, memory systems, and execution frameworks.

311 lines (270 loc) 8.56 kB
const { MCPStreamableHttpCommand } = require('../../lib/commands/MCPStreamableHttpCommand'); const http = require('http'); describe('MCPStreamableHttpCommand Integration Tests', () => { let command; let server; let port; beforeEach(() => { command = new MCPStreamableHttpCommand(); port = 3001 + Math.floor(Math.random() * 1000); // 随机端口避免冲突 }); afterEach(async () => { if (server && server.close) { await new Promise((resolve) => { server.close(() => { server = null; resolve(); }); }); } // 清理命令实例 if (command && command.server) { command.server = null; } }); describe('Streamable HTTP Server', () => { it('should start server and respond to health check', async () => { // 启动服务器 server = await command.execute({ transport: 'http', port, host: 'localhost' }); // 等待服务器启动 await new Promise(resolve => setTimeout(resolve, 100)); // 发送健康检查请求 const response = await makeHttpRequest({ hostname: 'localhost', port, path: '/health', method: 'GET' }); expect(response.statusCode).toBe(200); }, 5000); it('should handle MCP initialize request', async () => { // 启动服务器 server = await command.execute({ transport: 'http', port, host: 'localhost' }); // 等待服务器启动 await new Promise(resolve => setTimeout(resolve, 100)); // 发送初始化请求 const initRequest = { jsonrpc: '2.0', method: 'initialize', params: { protocolVersion: '2024-11-05', capabilities: {}, clientInfo: { name: 'test-client', version: '1.0.0' } }, id: 1 }; const response = await makeHttpRequest({ hostname: 'localhost', port, path: '/mcp', method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json, text/event-stream' } }, JSON.stringify(initRequest)); expect(response.statusCode).toBe(200); const responseData = JSON.parse(response.data); expect(responseData.jsonrpc).toBe('2.0'); expect(responseData.id).toBe(1); }, 5000); it('should handle tools/list request', async () => { // 启动服务器 server = await command.execute({ transport: 'http', port, host: 'localhost' }); // 等待服务器启动 await new Promise(resolve => setTimeout(resolve, 100)); // 先初始化 const initRequest = { jsonrpc: '2.0', method: 'initialize', params: { protocolVersion: '2024-11-05', capabilities: {}, clientInfo: { name: 'test-client', version: '1.0.0' } }, id: 1 }; const initResponse = await makeHttpRequest({ hostname: 'localhost', port, path: '/mcp', method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json, text/event-stream' } }, JSON.stringify(initRequest)); const initResponseData = JSON.parse(initResponse.data); const sessionId = initResponse.headers['mcp-session-id']; if (!sessionId) { throw new Error('Session ID not found in initialization response headers. Headers: ' + JSON.stringify(initResponse.headers) + ', Body: ' + JSON.stringify(initResponseData)); } // 发送工具列表请求 const toolsRequest = { jsonrpc: '2.0', method: 'tools/list', params: {}, id: 2 }; const response = await makeHttpRequest({ hostname: 'localhost', port, path: '/mcp', method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json, text/event-stream', 'mcp-session-id': sessionId } }, JSON.stringify(toolsRequest)); expect(response.statusCode).toBe(200); const responseData = JSON.parse(response.data); expect(responseData.result.tools).toBeDefined(); expect(Array.isArray(responseData.result.tools)).toBe(true); expect(responseData.result.tools.length).toBe(6); }, 5000); it('should handle tool call request', async () => { // 启动服务器 server = await command.execute({ transport: 'http', port, host: 'localhost' }); // 等待服务器启动 await new Promise(resolve => setTimeout(resolve, 100)); // 先初始化 const initRequest = { jsonrpc: '2.0', method: 'initialize', params: { protocolVersion: '2024-11-05', capabilities: {}, clientInfo: { name: 'test-client', version: '1.0.0' } }, id: 1 }; const initResponse = await makeHttpRequest({ hostname: 'localhost', port, path: '/mcp', method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json, text/event-stream' } }, JSON.stringify(initRequest)); const initResponseData = JSON.parse(initResponse.data); const sessionId = initResponse.headers['mcp-session-id']; if (!sessionId) { throw new Error('Session ID not found in initialization response headers. Headers: ' + JSON.stringify(initResponse.headers)); } // 发送工具调用请求 const toolCallRequest = { jsonrpc: '2.0', method: 'tools/call', params: { name: 'promptx_hello', arguments: {} }, id: 3 }; const response = await makeHttpRequest({ hostname: 'localhost', port, path: '/mcp', method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json, text/event-stream', 'mcp-session-id': sessionId } }, JSON.stringify(toolCallRequest)); expect(response.statusCode).toBe(200); const responseData = JSON.parse(response.data); expect(responseData.result).toBeDefined(); }, 5000); }); describe('Error Handling', () => { it('should handle invalid JSON requests', async () => { await command.execute({ transport: 'http', port, host: 'localhost' }); await new Promise(resolve => setTimeout(resolve, 100)); const response = await makeHttpRequest({ hostname: 'localhost', port, path: '/mcp', method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json, text/event-stream' } }, 'invalid json'); expect(response.statusCode).toBe(400); }, 5000); it('should handle missing session ID for non-initialize requests', async () => { await command.execute({ transport: 'http', port, host: 'localhost' }); await new Promise(resolve => setTimeout(resolve, 100)); const request = { jsonrpc: '2.0', method: 'tools/call', params: { name: 'promptx_hello', arguments: {} }, id: 1 }; const response = await makeHttpRequest({ hostname: 'localhost', port, path: '/mcp', method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json, text/event-stream' } }, JSON.stringify(request)); expect(response.statusCode).toBe(400); }, 5000); }); }); // Helper function to make HTTP requests function makeHttpRequest(options, data = null) { return new Promise((resolve, reject) => { // 如果有数据,添加Content-Length header if (data && options.headers) { options.headers['Content-Length'] = Buffer.byteLength(data); } const req = http.request(options, (res) => { let responseData = ''; res.on('data', (chunk) => { responseData += chunk; }); res.on('end', () => { resolve({ statusCode: res.statusCode, headers: res.headers, data: responseData }); }); }); req.on('error', reject); if (data) { req.write(data); } req.end(); }); }