Skip to main content
Glama
connectionManager.test.ts6.41 kB
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import type { Transport } from "@modelcontextprotocol/sdk/shared/transport.js"; import { beforeEach, describe, expect, it, type MockInstance, vi, } from "vitest"; import type { ILogger } from "../../src/core/logger.js"; import { ConnectionManager } from "../../src/server/connectionManager.js"; const mockServer = { close: vi.fn(), connect: vi.fn(), } as unknown as McpServer; const mockLogger = { sendLog: vi.fn(), } as ILogger; const mockTransport = {} as Transport; describe("ConnectionManager", () => { let connectionManager: ConnectionManager; let consoleErrorSpy: MockInstance; let consoleLogSpy: MockInstance; beforeEach(() => { vi.clearAllMocks(); consoleErrorSpy = vi.spyOn(console, "error").mockImplementation(() => {}); consoleLogSpy = vi.spyOn(console, "log").mockImplementation(() => {}); process.env.TD_WEB_SERVER_HOST = "http://127.0.0.1"; process.env.TD_WEB_SERVER_PORT = "9981"; connectionManager = new ConnectionManager(mockServer, mockLogger); }); describe("connect", () => { it("should successfully connect when MCP server is available", async () => { vi.mocked(mockServer.connect).mockResolvedValue(undefined); const result = await connectionManager.connect(mockTransport); expect(result.success).toBe(true); expect(mockServer.connect).toHaveBeenCalledWith(mockTransport); expect(mockLogger.sendLog).toHaveBeenCalledWith( expect.objectContaining({ data: "Server connected and ready to process requests: http://127.0.0.1:9981", level: "info", }), ); expect(connectionManager.isConnected()).toBe(true); }); it("should return success if already connected", async () => { vi.mocked(mockServer.connect).mockResolvedValue(undefined); await connectionManager.connect(mockTransport); const result = await connectionManager.connect(mockTransport); expect(result.success).toBe(true); expect(mockLogger.sendLog).toHaveBeenCalledWith( expect.objectContaining({ data: "MCP server already connected", level: "info", }), ); }); it("should handle MCP server connection failure", async () => { const connectionError = new Error("MCP connection failed"); vi.mocked(mockServer.connect).mockRejectedValue(connectionError); const result = await connectionManager.connect(mockTransport); expect(result.success).toBe(false); if (!result.success) { expect(result.error).toBe(connectionError); } expect(consoleErrorSpy).toHaveBeenCalledWith( "Fatal error starting server! Check TouchDesigner setup and starting webserver. For detailed setup instructions, see https://github.com/8beeeaaat/touchdesigner-mcp", connectionError, ); expect(connectionManager.isConnected()).toBe(false); }); it("should handle non-Error objects thrown during connection", async () => { vi.mocked(mockServer.connect).mockRejectedValue("String error"); const result = await connectionManager.connect(mockTransport); expect(result.success).toBe(false); if (!result.success) { expect(result.error.message).toBe("String error"); } expect(connectionManager.isConnected()).toBe(false); }); }); describe("disconnect", () => { it("should successfully disconnect when connected", async () => { vi.mocked(mockServer.connect).mockResolvedValue(undefined); await connectionManager.connect(mockTransport); vi.mocked(mockServer.close).mockResolvedValue(undefined); const result = await connectionManager.disconnect(); expect(result.success).toBe(true); expect(mockServer.close).toHaveBeenCalled(); expect(consoleLogSpy).toHaveBeenCalledWith( "MCP server disconnected from MCP", ); expect(connectionManager.isConnected()).toBe(false); }); it("should return success if not connected", async () => { const result = await connectionManager.disconnect(); expect(result.success).toBe(true); expect(consoleLogSpy).toHaveBeenCalledWith("MCP server not connected"); expect(mockServer.close).not.toHaveBeenCalled(); }); it("should handle server close failure", async () => { vi.mocked(mockServer.connect).mockResolvedValue(undefined); await connectionManager.connect(mockTransport); const closeError = new Error("Close failed"); vi.mocked(mockServer.close).mockRejectedValue(closeError); const result = await connectionManager.disconnect(); expect(result.success).toBe(false); if (!result.success) { expect(result.error).toBe(closeError); } expect(consoleErrorSpy).toHaveBeenCalledWith( "Error disconnecting from server", closeError, ); }); it("should handle non-Error objects during disconnect", async () => { vi.mocked(mockServer.connect).mockResolvedValue(undefined); await connectionManager.connect(mockTransport); vi.mocked(mockServer.close).mockRejectedValue("String error"); const result = await connectionManager.disconnect(); expect(result.success).toBe(false); if (!result.success) { expect(result.error.message).toBe("String error"); } }); }); describe("isConnected", () => { it("should return false when not connected", () => { expect(connectionManager.isConnected()).toBe(false); }); it("should return true when connected", async () => { vi.mocked(mockServer.connect).mockResolvedValue(undefined); await connectionManager.connect(mockTransport); expect(connectionManager.isConnected()).toBe(true); }); it("should return false after disconnect", async () => { vi.mocked(mockServer.connect).mockResolvedValue(undefined); await connectionManager.connect(mockTransport); vi.mocked(mockServer.close).mockResolvedValue(undefined); await connectionManager.disconnect(); expect(connectionManager.isConnected()).toBe(false); }); }); describe("error messages", () => { it("should display helpful setup instructions on connection failure", async () => { const connectionError = new Error("Connection failed"); vi.mocked(mockServer.connect).mockRejectedValue(connectionError); await connectionManager.connect(mockTransport); expect(consoleErrorSpy).toHaveBeenCalledWith( "Fatal error starting server! Check TouchDesigner setup and starting webserver. For detailed setup instructions, see https://github.com/8beeeaaat/touchdesigner-mcp", connectionError, ); }); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/8beeeaaat/touchdesigner-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server