Skip to main content
Glama

1MCP Server

agentConfig.test.ts14.1 kB
import { beforeEach, describe, expect, it, vi } from 'vitest'; import { AgentConfigManager } from './agentConfig.js'; // Mock constants vi.mock('@src/constants.js', () => ({ HOST: 'localhost', PORT: 3050, AUTH_CONFIG: { SERVER: { DEFAULT_ENABLED: false, SESSION: { TTL_MINUTES: 1440, }, AUTH_CODE: { TTL_MS: 60000, }, TOKEN: { TTL_MS: 86400000, }, }, }, RATE_LIMIT_CONFIG: { OAUTH: { WINDOW_MS: 900000, MAX: 100, }, }, })); describe('AgentConfigManager', () => { beforeEach(() => { // Reset singleton instance before each test // @ts-expect-error - Accessing private property for testing AgentConfigManager.instance = undefined; }); describe('Singleton Pattern', () => { it('should return the same instance when called multiple times', () => { const instance1 = AgentConfigManager.getInstance(); const instance2 = AgentConfigManager.getInstance(); expect(instance1).toBe(instance2); }); it('should maintain configuration state across getInstance calls', () => { const instance1 = AgentConfigManager.getInstance(); instance1.updateConfig({ host: 'test.example.com' }); const instance2 = AgentConfigManager.getInstance(); expect(instance2.getConfig().host).toBe('test.example.com'); }); }); describe('Default Configuration', () => { it('should initialize with correct default values', () => { const configManager = AgentConfigManager.getInstance(); const config = configManager.getConfig(); expect(config).toEqual({ host: 'localhost', port: 3050, trustProxy: 'loopback', auth: { enabled: false, sessionTtlMinutes: 1440, oauthCodeTtlMs: 60000, oauthTokenTtlMs: 86400000, }, rateLimit: { windowMs: 900000, max: 100, }, features: { auth: false, scopeValidation: false, enhancedSecurity: false, configReload: true, envSubstitution: true, sessionPersistence: true, clientNotifications: true, }, health: { detailLevel: 'minimal', }, asyncLoading: { enabled: false, initialLoadTimeoutMs: 30000, waitForMinimumServers: 0, batchNotifications: true, batchDelayMs: 1000, notifyOnServerReady: true, }, configReload: { debounceMs: 500, }, sessionPersistence: { persistRequests: 100, persistIntervalMinutes: 5, backgroundFlushSeconds: 60, }, }); }); it('should have trustProxy default to loopback', () => { const configManager = AgentConfigManager.getInstance(); expect(configManager.get('trustProxy')).toBe('loopback'); }); }); describe('Configuration Updates', () => { let configManager: AgentConfigManager; beforeEach(() => { configManager = AgentConfigManager.getInstance(); }); it('should update basic configuration fields', () => { configManager.updateConfig({ host: 'example.com', port: 8080, externalUrl: 'https://api.example.com', trustProxy: true, }); const config = configManager.getConfig(); expect(config.host).toBe('example.com'); expect(config.port).toBe(8080); expect(config.externalUrl).toBe('https://api.example.com'); expect(config.trustProxy).toBe(true); }); it('should update auth configuration partially', () => { configManager.updateConfig({ auth: { enabled: true, sessionTtlMinutes: 720, } as any, }); const config = configManager.getConfig(); expect(config.auth.enabled).toBe(true); expect(config.auth.sessionTtlMinutes).toBe(720); // Should preserve other auth fields expect(config.auth.oauthCodeTtlMs).toBe(60000); expect(config.auth.oauthTokenTtlMs).toBe(86400000); }); it('should update rate limit configuration partially', () => { configManager.updateConfig({ rateLimit: { windowMs: 300000, max: 50, }, }); const config = configManager.getConfig(); expect(config.rateLimit.windowMs).toBe(300000); expect(config.rateLimit.max).toBe(50); }); it('should update features configuration partially', () => { configManager.updateConfig({ features: { auth: true, enhancedSecurity: true, } as any, }); const config = configManager.getConfig(); expect(config.features.auth).toBe(true); expect(config.features.enhancedSecurity).toBe(true); // Should preserve other feature fields expect(config.features.scopeValidation).toBe(false); }); it('should handle multiple simultaneous updates', () => { configManager.updateConfig({ host: 'multi-test.com', trustProxy: '192.168.1.0/24', auth: { enabled: true, sessionTtlMinutes: 480, } as any, features: { enhancedSecurity: true, } as any, }); const config = configManager.getConfig(); expect(config.host).toBe('multi-test.com'); expect(config.trustProxy).toBe('192.168.1.0/24'); expect(config.auth.enabled).toBe(true); expect(config.auth.sessionTtlMinutes).toBe(480); expect(config.features.enhancedSecurity).toBe(true); }); }); describe('Generic Getter Method', () => { let configManager: AgentConfigManager; beforeEach(() => { configManager = AgentConfigManager.getInstance(); }); it('should provide type-safe access to top-level properties', () => { expect(configManager.get('host')).toBe('localhost'); expect(configManager.get('port')).toBe(3050); expect(configManager.get('trustProxy')).toBe('loopback'); }); it('should provide type-safe access to nested properties', () => { expect(configManager.get('auth').enabled).toBe(false); expect(configManager.get('auth').sessionTtlMinutes).toBe(1440); expect(configManager.get('rateLimit').windowMs).toBe(900000); expect(configManager.get('rateLimit').max).toBe(100); expect(configManager.get('features').auth).toBe(false); expect(configManager.get('features').scopeValidation).toBe(false); expect(configManager.get('health').detailLevel).toBe('minimal'); expect(configManager.get('asyncLoading').enabled).toBe(false); }); it('should return updated values after configuration changes', () => { configManager.updateConfig({ host: 'updated.com', auth: { sessionTtlMinutes: 720 } as any, features: { auth: true } as any, }); expect(configManager.get('host')).toBe('updated.com'); expect(configManager.get('auth').sessionTtlMinutes).toBe(720); expect(configManager.get('features').auth).toBe(true); }); it('should maintain type safety with TypeScript', () => { // These should compile without type errors const host: string = configManager.get('host'); const port: number = configManager.get('port'); const authEnabled: boolean = configManager.get('features').auth; const detailLevel: 'full' | 'basic' | 'minimal' = configManager.get('health').detailLevel; expect(typeof host).toBe('string'); expect(typeof port).toBe('number'); expect(typeof authEnabled).toBe('boolean'); expect(typeof detailLevel).toBe('string'); }); }); describe('Convenience Methods (High Usage)', () => { let configManager: AgentConfigManager; beforeEach(() => { configManager = AgentConfigManager.getInstance(); }); it('should return deep copy of configuration in getConfig', () => { const config = configManager.getConfig(); config.host = 'modified-host'; const freshConfig = configManager.getConfig(); expect(freshConfig.host).toBe('localhost'); // Should not be modified }); it('should return correct trust proxy value', () => { expect(configManager.get('trustProxy')).toBe('loopback'); configManager.updateConfig({ trustProxy: true }); expect(configManager.get('trustProxy')).toBe(true); configManager.updateConfig({ trustProxy: '127.0.0.1' }); expect(configManager.get('trustProxy')).toBe('127.0.0.1'); configManager.updateConfig({ trustProxy: false }); expect(configManager.get('trustProxy')).toBe(false); }); it('should return correct auth status', () => { expect(configManager.get('features').auth).toBe(false); configManager.updateConfig({ features: { auth: true } as any, }); expect(configManager.get('features').auth).toBe(true); }); it('should return correct scope validation status', () => { expect(configManager.get('features').scopeValidation).toBe(false); configManager.updateConfig({ features: { scopeValidation: true } as any, }); expect(configManager.get('features').scopeValidation).toBe(true); }); it('should return correct enhanced security status', () => { expect(configManager.get('features').enhancedSecurity).toBe(false); configManager.updateConfig({ features: { enhancedSecurity: true } as any, }); expect(configManager.get('features').enhancedSecurity).toBe(true); }); it('should return correct external URL', () => { expect(configManager.get('externalUrl')).toBeUndefined(); configManager.updateConfig({ externalUrl: 'https://external.example.com', }); expect(configManager.get('externalUrl')).toBe('https://external.example.com'); }); it('should return correct server URL - using external URL when set', () => { expect(configManager.getUrl()).toBe('http://localhost:3050'); configManager.updateConfig({ externalUrl: 'https://external.example.com', }); expect(configManager.getUrl()).toBe('https://external.example.com'); }); it('should return correct server URL - fallback to host:port', () => { configManager.updateConfig({ host: 'custom.host.com', port: 9000, }); expect(configManager.getUrl()).toBe('http://custom.host.com:9000'); }); it('should return correct health detail level', () => { expect(configManager.get('health').detailLevel).toBe('minimal'); configManager.updateConfig({ health: { detailLevel: 'full' }, }); expect(configManager.get('health').detailLevel).toBe('full'); }); it('should return correct async loading status', () => { expect(configManager.get('asyncLoading').enabled).toBe(false); configManager.updateConfig({ asyncLoading: { enabled: true } as any, }); expect(configManager.get('asyncLoading').enabled).toBe(true); }); it('should return correct config reload status', () => { expect(configManager.get('features').configReload).toBe(true); configManager.updateConfig({ features: { configReload: false } as any, }); expect(configManager.get('features').configReload).toBe(false); }); it('should return correct client notifications status', () => { expect(configManager.get('features').clientNotifications).toBe(true); configManager.updateConfig({ features: { clientNotifications: false } as any, }); expect(configManager.get('features').clientNotifications).toBe(false); }); }); describe('Trust Proxy Value Types', () => { let configManager: AgentConfigManager; beforeEach(() => { configManager = AgentConfigManager.getInstance(); }); it('should handle boolean trust proxy values', () => { configManager.updateConfig({ trustProxy: true }); expect(configManager.get('trustProxy')).toBe(true); configManager.updateConfig({ trustProxy: false }); expect(configManager.get('trustProxy')).toBe(false); }); it('should handle string preset trust proxy values', () => { const presets = ['loopback', 'linklocal', 'uniquelocal']; presets.forEach((preset) => { configManager.updateConfig({ trustProxy: preset }); expect(configManager.get('trustProxy')).toBe(preset); }); }); it('should handle IP address trust proxy values', () => { const ipAddresses = ['127.0.0.1', '192.168.1.1', '::1']; ipAddresses.forEach((ip) => { configManager.updateConfig({ trustProxy: ip }); expect(configManager.get('trustProxy')).toBe(ip); }); }); it('should handle CIDR range trust proxy values', () => { const cidrs = ['192.168.0.0/16', '10.0.0.0/8', '172.16.0.0/12']; cidrs.forEach((cidr) => { configManager.updateConfig({ trustProxy: cidr }); expect(configManager.get('trustProxy')).toBe(cidr); }); }); }); describe('Configuration State Persistence', () => { it('should maintain configuration state across multiple method calls', () => { const configManager = AgentConfigManager.getInstance(); configManager.updateConfig({ host: 'persistent.com', trustProxy: 'linklocal', features: { auth: true } as any, }); // Multiple getter calls should return consistent results expect(configManager.get('trustProxy')).toBe('linklocal'); expect(configManager.get('features').auth).toBe(true); expect(configManager.getConfig().host).toBe('persistent.com'); // State should persist after additional updates configManager.updateConfig({ port: 4000 }); expect(configManager.get('trustProxy')).toBe('linklocal'); expect(configManager.get('features').auth).toBe(true); expect(configManager.getConfig().host).toBe('persistent.com'); expect(configManager.getConfig().port).toBe(4000); }); }); });

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/1mcp-app/agent'

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