index.test.ts•9.79 kB
import { describe, expect, it } from 'vitest';
// This is a simplified test for the index.ts entry point
// Testing CLI entry points with full execution is complex due to side effects
// We focus on ensuring the basic structure and imports work correctly
describe('Index Module', () => {
  describe('Module Structure', () => {
    it('should have required imports available', async () => {
      // Test that the main dependencies are importable
      expect(async () => {
        await import('yargs');
      }).not.toThrow();
      expect(async () => {
        await import('yargs/helpers');
      }).not.toThrow();
      expect(async () => {
        await import('@modelcontextprotocol/sdk/server/stdio.js');
      }).not.toThrow();
      expect(async () => {
        await import('./server.js');
      }).not.toThrow();
      expect(async () => {
        await import('@src/logger/logger.js');
      }).not.toThrow();
    });
    it('should export expected functions from dependencies', async () => {
      const yargs = await import('yargs');
      expect(typeof yargs.default).toBe('function');
      const { hideBin } = await import('yargs/helpers');
      expect(typeof hideBin).toBe('function');
      const { StdioServerTransport } = await import('@modelcontextprotocol/sdk/server/stdio.js');
      expect(typeof StdioServerTransport).toBe('function');
      const { setupServer } = await import('./server.js');
      expect(typeof setupServer).toBe('function');
      const logger = await import('@src/logger/logger.js');
      expect(typeof logger.default).toBe('object');
      expect(typeof logger.enableConsoleTransport).toBe('function');
    });
    it('should have server manager available', async () => {
      const { ServerManager } = await import('./core/server/serverManager.js');
      expect(typeof ServerManager).toBe('function');
    });
    it('should have config managers available', async () => {
      const { McpConfigManager } = await import('@src/config/mcpConfigManager.js');
      expect(typeof McpConfigManager.getInstance).toBe('function');
      const { AgentConfigManager } = await import('@src/core/server/agentConfig.js');
      expect(typeof AgentConfigManager.getInstance).toBe('function');
    });
    it('should have transport classes available', async () => {
      const { ExpressServer } = await import('./transport/http/server.js');
      expect(typeof ExpressServer).toBe('function');
      const { StdioServerTransport } = await import('@modelcontextprotocol/sdk/server/stdio.js');
      expect(typeof StdioServerTransport).toBe('function');
    });
    it('should have constants defined', async () => {
      const { PORT, HOST } = await import('@src/constants.js');
      expect(typeof PORT).toBe('number');
      expect(typeof HOST).toBe('string');
    });
    it('should have services available', async () => {
      const configReloadService = await import('./application/services/configReloadService.js');
      expect(typeof configReloadService.default).toBe('object');
      expect(typeof configReloadService.default.stop).toBe('function');
    });
  });
  describe('CLI Argument Structure', () => {
    it('should define expected CLI options structure', () => {
      // Test the structure of CLI options that would be used by yargs
      const expectedOptions = {
        transport: {
          alias: 't',
          describe: 'Transport type to use (stdio or http, sse is deprecated)',
          type: 'string',
          choices: ['stdio', 'http', 'sse'],
          default: 'http',
        },
        port: {
          alias: 'P',
          describe: 'HTTP port to listen on, applicable when transport is http',
          type: 'number',
        },
        host: {
          alias: 'H',
          describe: 'HTTP host to listen on, applicable when transport is http',
          type: 'string',
        },
        config: {
          alias: 'c',
          describe: 'Path to the config file',
          type: 'string',
        },
        tags: {
          alias: 'g',
          describe: 'Tags to filter clients (comma-separated)',
          type: 'string',
        },
        pagination: {
          alias: 'p',
          describe: 'Enable pagination',
          type: 'boolean',
          default: false,
        },
        auth: {
          describe: 'Enable authentication (OAuth 2.1) - deprecated, use --enable-auth',
          type: 'boolean',
          default: false,
        },
        'enable-auth': {
          describe: 'Enable authentication (OAuth 2.1)',
          type: 'boolean',
          default: false,
        },
        'enable-scope-validation': {
          describe: 'Enable tag-based scope validation',
          type: 'boolean',
          default: true,
        },
        'enable-enhanced-security': {
          describe: 'Enable enhanced security middleware',
          type: 'boolean',
          default: false,
        },
      };
      // Verify the option structure is well-formed
      expect(expectedOptions.transport.choices).toContain('stdio');
      expect(expectedOptions.transport.choices).toContain('http');
      expect(expectedOptions.transport.choices).toContain('sse');
      expect(expectedOptions.transport.default).toBe('http');
      expect(expectedOptions.pagination.default).toBe(false);
      expect(expectedOptions.auth.default).toBe(false);
      expect(expectedOptions['enable-auth'].default).toBe(false);
      expect(expectedOptions['enable-scope-validation'].default).toBe(true);
      expect(expectedOptions['enable-enhanced-security'].default).toBe(false);
    });
  });
  describe('Environment Variables', () => {
    it('should support ONE_MCP prefix for environment variables', () => {
      // Test that the environment variable prefix is correctly set up
      const envPrefix = 'ONE_MCP';
      expect(typeof envPrefix).toBe('string');
      expect(envPrefix).toBe('ONE_MCP');
    });
  });
  describe('Signal Handling', () => {
    it('should define expected shutdown signals', () => {
      const expectedSignals = ['SIGINT', 'SIGTERM', 'SIGHUP'];
      expectedSignals.forEach((signal) => {
        expect(typeof signal).toBe('string');
        expect(signal.startsWith('SIG')).toBe(true);
      });
    });
  });
  describe('Type Safety', () => {
    it('should have proper TypeScript types', async () => {
      // Test that imports have the expected TypeScript structure
      const logger = await import('@src/logger/logger.js');
      // Logger should have the expected methods
      expect(logger.default).toHaveProperty('info');
      expect(logger.default).toHaveProperty('error');
      expect(logger.default).toHaveProperty('warn');
      expect(logger.default).toHaveProperty('debug');
    });
    it('should handle process events correctly', () => {
      // Test that process event handling structure is correct
      expect(typeof process.on).toBe('function');
      expect(typeof process.exit).toBe('function');
    });
  });
  describe('Module Loading', () => {
    it('should load source map support', () => {
      // Test that source-map-support is properly configured
      expect(() => {
        // Source map support is loaded at runtime, just verify the test structure
        expect(true).toBe(true);
      }).not.toThrow();
    });
    it('should handle module resolution', async () => {
      // Test that all required modules can be resolved
      const modules = [
        'yargs',
        'yargs/helpers',
        '@modelcontextprotocol/sdk/server/stdio.js',
        './server.js',
        '@src/logger/logger.js',
        './application/services/configReloadService.js',
        './core/server/serverManager.js',
        '@src/config/mcpConfigManager.js',
        './transport/http/server.js',
        '@src/core/server/agentConfig.js',
        '@src/constants.js',
      ];
      for (const moduleName of modules) {
        expect(async () => {
          await import(moduleName);
        }).not.toThrow();
      }
    });
  });
  describe('Default Values', () => {
    it('should have sensible default values', async () => {
      const { PORT, HOST } = await import('@src/constants.js');
      // Test that default values are sensible
      expect(PORT).toBeGreaterThan(0);
      expect(PORT).toBeLessThan(65536);
      expect(typeof HOST).toBe('string');
      expect(HOST.length).toBeGreaterThan(0);
    });
    it('should have consistent default configuration', () => {
      // Test default configuration consistency
      const defaultSessionTtl = 24 * 60; // 24 hours in minutes
      const defaultRateLimitWindow = 15; // 15 minutes
      const defaultRateLimitMax = 100;
      expect(defaultSessionTtl).toBe(1440);
      expect(defaultRateLimitWindow).toBe(15);
      expect(defaultRateLimitMax).toBe(100);
    });
  });
  describe('Command Validation', () => {
    it('should have yargs strict mode configuration', async () => {
      const yargs = await import('yargs');
      const yargsInstance = yargs.default([]);
      // Verify that yargs has the strict method available
      expect(typeof yargsInstance.strict).toBe('function');
    });
    it('should have fail handler for unknown commands', async () => {
      const yargs = await import('yargs');
      const yargsInstance = yargs.default([]);
      // Verify that yargs has the fail method available for custom error handling
      expect(typeof yargsInstance.fail).toBe('function');
    });
    it('should validate command structure', () => {
      // Test that valid commands are defined
      const validCommands = ['app', 'mcp', 'preset', 'serve', 'proxy'];
      validCommands.forEach((cmd) => {
        expect(typeof cmd).toBe('string');
        expect(cmd.length).toBeGreaterThan(0);
      });
    });
  });
});