import { describe, it, expect, vi } from 'vitest'; import { refreshUpstreams } from '../src/discovery.js'; import { McpRouter } from '../src/router.js'; function mockMcpdClient(servers: Array<{ id: string; name: string; transport: string }>) { return { baseUrl: 'http://test:3100', token: 'test-token', get: vi.fn(async () => servers), post: vi.fn(async () => ({ result: {} })), put: vi.fn(), delete: vi.fn(), forward: vi.fn(), }; } describe('refreshUpstreams', () => { it('registers mcpd servers as upstreams', async () => { const router = new McpRouter(); const client = mockMcpdClient([ { id: 'srv-1', name: 'slack', transport: 'stdio' }, { id: 'srv-2', name: 'github', transport: 'stdio' }, ]); const registered = await refreshUpstreams(router, client as any); expect(registered).toEqual(['slack', 'github']); expect(router.getUpstreamNames()).toContain('slack'); expect(router.getUpstreamNames()).toContain('github'); }); it('removes stale upstreams', async () => { const router = new McpRouter(); // First refresh: 2 servers const client1 = mockMcpdClient([ { id: 'srv-1', name: 'slack', transport: 'stdio' }, { id: 'srv-2', name: 'github', transport: 'stdio' }, ]); await refreshUpstreams(router, client1 as any); expect(router.getUpstreamNames()).toHaveLength(2); // Second refresh: only 1 server const client2 = mockMcpdClient([ { id: 'srv-1', name: 'slack', transport: 'stdio' }, ]); await refreshUpstreams(router, client2 as any); expect(router.getUpstreamNames()).toEqual(['slack']); }); it('does not duplicate existing upstreams', async () => { const router = new McpRouter(); const client = mockMcpdClient([ { id: 'srv-1', name: 'slack', transport: 'stdio' }, ]); await refreshUpstreams(router, client as any); await refreshUpstreams(router, client as any); expect(router.getUpstreamNames()).toEqual(['slack']); }); it('handles empty server list', async () => { const router = new McpRouter(); const client = mockMcpdClient([]); const registered = await refreshUpstreams(router, client as any); expect(registered).toEqual([]); expect(router.getUpstreamNames()).toHaveLength(0); }); });