diff options
| author | Jack Wotherspoon <[email protected]> | 2025-08-06 11:52:29 -0400 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-08-06 15:52:29 +0000 |
| commit | ca4c745e3b620e3ac4eca24b610cc7b936c0a50d (patch) | |
| tree | eb1b9cfb46bd4fa2e7f9631828b0704df1050eb7 /packages/cli/src/commands/mcp/list.test.ts | |
| parent | b38f377c9a2672e88dd15119b38d908c0f00b54a (diff) | |
feat(mcp): add `gemini mcp` commands for `add`, `remove` and `list` (#5481)
Diffstat (limited to 'packages/cli/src/commands/mcp/list.test.ts')
| -rw-r--r-- | packages/cli/src/commands/mcp/list.test.ts | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/packages/cli/src/commands/mcp/list.test.ts b/packages/cli/src/commands/mcp/list.test.ts new file mode 100644 index 00000000..daf2e3d7 --- /dev/null +++ b/packages/cli/src/commands/mcp/list.test.ts @@ -0,0 +1,154 @@ +/** + * @license + * Copyright 2025 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import { vi, describe, it, expect, beforeEach, afterEach } from 'vitest'; +import { listMcpServers } from './list.js'; +import { loadSettings } from '../../config/settings.js'; +import { loadExtensions } from '../../config/extension.js'; +import { createTransport } from '@google/gemini-cli-core'; +import { Client } from '@modelcontextprotocol/sdk/client/index.js'; + +vi.mock('../../config/settings.js'); +vi.mock('../../config/extension.js'); +vi.mock('@google/gemini-cli-core'); +vi.mock('@modelcontextprotocol/sdk/client/index.js'); + +const mockedLoadSettings = loadSettings as vi.Mock; +const mockedLoadExtensions = loadExtensions as vi.Mock; +const mockedCreateTransport = createTransport as vi.Mock; +const MockedClient = Client as vi.Mock; + +interface MockClient { + connect: vi.Mock; + ping: vi.Mock; + close: vi.Mock; +} + +interface MockTransport { + close: vi.Mock; +} + +describe('mcp list command', () => { + let consoleSpy: vi.SpyInstance; + let mockClient: MockClient; + let mockTransport: MockTransport; + + beforeEach(() => { + vi.resetAllMocks(); + + consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {}); + + mockTransport = { close: vi.fn() }; + mockClient = { + connect: vi.fn(), + ping: vi.fn(), + close: vi.fn(), + }; + + MockedClient.mockImplementation(() => mockClient); + mockedCreateTransport.mockResolvedValue(mockTransport); + mockedLoadExtensions.mockReturnValue([]); + }); + + afterEach(() => { + consoleSpy.mockRestore(); + }); + + it('should display message when no servers configured', async () => { + mockedLoadSettings.mockReturnValue({ merged: { mcpServers: {} } }); + + await listMcpServers(); + + expect(consoleSpy).toHaveBeenCalledWith('No MCP servers configured.'); + }); + + it('should display different server types with connected status', async () => { + mockedLoadSettings.mockReturnValue({ + merged: { + mcpServers: { + 'stdio-server': { command: '/path/to/server', args: ['arg1'] }, + 'sse-server': { url: 'https://example.com/sse' }, + 'http-server': { httpUrl: 'https://example.com/http' }, + }, + }, + }); + + mockClient.connect.mockResolvedValue(undefined); + mockClient.ping.mockResolvedValue(undefined); + + await listMcpServers(); + + expect(consoleSpy).toHaveBeenCalledWith('Configured MCP servers:\n'); + expect(consoleSpy).toHaveBeenCalledWith( + expect.stringContaining( + 'stdio-server: /path/to/server arg1 (stdio) - Connected', + ), + ); + expect(consoleSpy).toHaveBeenCalledWith( + expect.stringContaining( + 'sse-server: https://example.com/sse (sse) - Connected', + ), + ); + expect(consoleSpy).toHaveBeenCalledWith( + expect.stringContaining( + 'http-server: https://example.com/http (http) - Connected', + ), + ); + }); + + it('should display disconnected status when connection fails', async () => { + mockedLoadSettings.mockReturnValue({ + merged: { + mcpServers: { + 'test-server': { command: '/test/server' }, + }, + }, + }); + + mockClient.connect.mockRejectedValue(new Error('Connection failed')); + + await listMcpServers(); + + expect(consoleSpy).toHaveBeenCalledWith( + expect.stringContaining( + 'test-server: /test/server (stdio) - Disconnected', + ), + ); + }); + + it('should merge extension servers with config servers', async () => { + mockedLoadSettings.mockReturnValue({ + merged: { + mcpServers: { 'config-server': { command: '/config/server' } }, + }, + }); + + mockedLoadExtensions.mockReturnValue([ + { + config: { + name: 'test-extension', + mcpServers: { 'extension-server': { command: '/ext/server' } }, + }, + }, + ]); + + mockClient.connect.mockResolvedValue(undefined); + mockClient.ping.mockResolvedValue(undefined); + + await listMcpServers(); + + expect(consoleSpy).toHaveBeenCalledWith( + expect.stringContaining( + 'config-server: /config/server (stdio) - Connected', + ), + ); + expect(consoleSpy).toHaveBeenCalledWith( + expect.stringContaining( + 'extension-server: /ext/server (stdio) - Connected', + ), + ); + }); +}); |
