Skip to main content
Glama
index.test.ts9.43 kB
/** * This test module tests that index.ts can be imported and works correctly */ import { vi } from 'vitest'; // Mock logger first const mockLogger = { info: vi.fn(), debug: vi.fn(), error: vi.fn(), warn: vi.fn(), }; vi.mock('../utils/logging/logger.js', () => ({ createLogger: vi.fn(() => mockLogger), })); // Mock feature flags const mockFeatures = { toolDiscovery: false, enhancedLogging: false, metrics: false, cache: false, }; vi.mock('../config/features.js', () => ({ getFeatureFlags: vi.fn(() => mockFeatures), logFeatureFlags: vi.fn(), })); // Mock environment config vi.mock('../config/environment.js', () => ({ getEnvironmentConfig: vi.fn(() => ({ discovery: { directories: ['./src/tools/test'], patterns: ['*.tool.js', '*.tool.mjs'], recursive: true, includeCategories: [], excludeCategories: [], includeTags: [], excludeTags: [], }, })), })); // Set up all mocks BEFORE any imports - using unstable_mockModule for ES modules vi.mock('@modelcontextprotocol/sdk/server/mcp.js', () => ({ McpServer: vi.fn().mockImplementation(() => ({ registerTool: vi.fn(), connect: vi.fn(), setRequestHandler: vi.fn(), })), })); vi.mock('@modelcontextprotocol/sdk/server/stdio.js', () => ({ StdioServerTransport: vi.fn(), })); vi.mock('../server/tool-registry.js', () => ({ ToolRegistry: vi.fn().mockImplementation(() => ({ registerTool: vi.fn(), getTools: vi.fn().mockReturnValue([]), })), })); vi.mock('../handlers/base/handler.factory.js', () => ({ createDefaultHandlerDeps: vi.fn(() => ({ client: {}, logger: { info: vi.fn(), debug: vi.fn(), error: vi.fn(), warn: vi.fn(), }, })), createBaseHandlerFactory: vi.fn(), })); vi.mock('../server/tool-registration.js', () => ({ registerDeepSourceTools: vi.fn(), })); const mockMcpServer = { getRegisteredTools: vi.fn().mockReturnValue(['projects', 'issues']), getMcpServer: vi.fn().mockReturnValue({ registerTool: vi.fn(), }), start: vi.fn(), discoverTools: vi.fn().mockResolvedValue([]), getToolsInfo: vi.fn().mockReturnValue([]), }; vi.mock('../server/mcp-server.js', () => ({ DeepSourceMCPServer: { create: vi.fn().mockResolvedValue(mockMcpServer), }, })); // Now import test utilities after mocks are set const { describe, it, expect, beforeAll, afterAll, beforeEach, afterEach } = await import('vitest'); describe('index.ts module', () => { // Import the module let indexModule: { mcpServer: { current: { getRegisteredTools: () => string[]; getMcpServer: () => unknown; start?: () => Promise<void>; }; }; getMcpServer: () => unknown; handleCliArgs: (args: string[]) => boolean; initializeServer: () => Promise<void>; }; let originalEnv: typeof process.env; let consoleLogSpy: ReturnType<typeof vi.spyOn>; beforeAll(async () => { // Save original env originalEnv = { ...process.env }; // Set required environment variables for testing process.env.DEEPSOURCE_API_KEY = 'test-key'; process.env.NODE_ENV = 'test'; // Import the module - this should trigger the code execution // and provide us with the exported mcpServer object indexModule = await import('../index.js'); }); beforeEach(() => { consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => { // Intentionally empty - suppressing console output during tests return undefined; }); vi.clearAllMocks(); }); afterEach(() => { consoleLogSpy.mockRestore(); }); afterAll(() => { // Restore original env process.env = originalEnv; }); it('should export an mcpServer instance', () => { expect(indexModule.mcpServer).toBeDefined(); expect(indexModule.mcpServer.current).toBeDefined(); }); it('should have a server with appropriate methods', () => { expect(typeof indexModule.mcpServer.current.getRegisteredTools).toBe('function'); expect(typeof indexModule.getMcpServer).toBe('function'); }); describe('handleCliArgs', () => { it('should handle --version flag', () => { const result = indexModule.handleCliArgs(['--version']); expect(result).toBe(true); expect(consoleLogSpy).toHaveBeenCalledWith( expect.stringContaining('deepsource-mcp-server version') ); }); it('should handle -v flag', () => { const result = indexModule.handleCliArgs(['-v']); expect(result).toBe(true); expect(consoleLogSpy).toHaveBeenCalledWith( expect.stringContaining('deepsource-mcp-server version') ); }); it('should show enabled features with version flag when features are enabled', () => { mockFeatures.toolDiscovery = true; mockFeatures.enhancedLogging = true; const result = indexModule.handleCliArgs(['--version']); expect(result).toBe(true); expect(consoleLogSpy).toHaveBeenCalledWith( expect.stringContaining('Enabled features: toolDiscovery, enhancedLogging') ); // Reset mockFeatures.toolDiscovery = false; mockFeatures.enhancedLogging = false; }); it('should handle --help flag', () => { const result = indexModule.handleCliArgs(['--help']); expect(result).toBe(true); expect(consoleLogSpy).toHaveBeenCalledWith(expect.stringContaining('DeepSource MCP Server')); expect(consoleLogSpy).toHaveBeenCalledWith( expect.stringContaining('Usage: deepsource-mcp-server') ); }); it('should return false for unknown args', () => { const result = indexModule.handleCliArgs(['--unknown']); expect(result).toBe(false); expect(consoleLogSpy).not.toHaveBeenCalled(); }); }); describe('Tool discovery and feature flags', () => { it('should log feature flags when enhancedLogging is enabled', async () => { const { logFeatureFlags } = await import('../config/features.js'); mockFeatures.enhancedLogging = true; await indexModule.initializeServer(); expect(logFeatureFlags).toHaveBeenCalled(); // Reset mockFeatures.enhancedLogging = false; }); it('should log feature flags in development mode', async () => { const { logFeatureFlags } = await import('../config/features.js'); const originalEnv = process.env.NODE_ENV; process.env.NODE_ENV = 'development'; await indexModule.initializeServer(); expect(logFeatureFlags).toHaveBeenCalled(); // Reset process.env.NODE_ENV = originalEnv; }); it('should perform tool discovery when feature is enabled', async () => { mockFeatures.toolDiscovery = true; await indexModule.initializeServer(); expect(mockMcpServer.discoverTools).toHaveBeenCalled(); expect(mockLogger.info).toHaveBeenCalledWith( 'Tool discovery enabled, scanning for additional tools...' ); // Reset mockFeatures.toolDiscovery = false; }); it('should log discovered tools when found', async () => { mockFeatures.toolDiscovery = true; mockMcpServer.discoverTools.mockResolvedValueOnce(['tool1', 'tool2']); await indexModule.initializeServer(); expect(mockMcpServer.discoverTools).toHaveBeenCalled(); expect(mockLogger.info).toHaveBeenCalledWith( 'Discovered 2 additional tools', expect.objectContaining({ tools: ['tool1', 'tool2'] }) ); // Reset mockFeatures.toolDiscovery = false; mockMcpServer.discoverTools.mockResolvedValue([]); }); it('should not log when no tools discovered', async () => { mockFeatures.toolDiscovery = true; mockMcpServer.discoverTools.mockResolvedValueOnce([]); await indexModule.initializeServer(); expect(mockMcpServer.discoverTools).toHaveBeenCalled(); // Should not log about discovered tools when array is empty expect(mockLogger.info).not.toHaveBeenCalledWith( expect.stringContaining('Discovered'), expect.any(Object) ); // Reset mockFeatures.toolDiscovery = false; }); it('should pass discovery config when tool discovery is enabled', async () => { const { DeepSourceMCPServer } = await import('../server/mcp-server.js'); mockFeatures.toolDiscovery = true; await indexModule.initializeServer(); expect(DeepSourceMCPServer.create).toHaveBeenCalledWith( expect.objectContaining({ autoRegisterTools: true, autoStart: false, discoveryConfig: { directories: ['./src/tools/test'], patterns: ['*.tool.js', '*.tool.mjs'], recursive: true, includeCategories: [], excludeCategories: [], includeTags: [], excludeTags: [], }, }) ); // Reset mockFeatures.toolDiscovery = false; }); it('should log enabled features on startup', async () => { mockFeatures.toolDiscovery = true; mockFeatures.metrics = true; await indexModule.initializeServer(); expect(mockLogger.info).toHaveBeenCalledWith( 'DeepSource MCP Server initialized successfully', expect.objectContaining({ features: ['toolDiscovery', 'metrics'], }) ); // Reset mockFeatures.toolDiscovery = false; mockFeatures.metrics = false; }); }); });

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/sapientpants/deepsource-mcp-server'

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