Path: blob/main/extensions/copilot/src/extension/mcp/test/vscode-node/commands.spec.ts
13405 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { beforeEach, describe, expect, it } from 'vitest';6import { ILogService } from '../../../../platform/log/common/logService';7import { ITestingServicesAccessor, TestingServiceCollection } from '../../../../platform/test/node/services';8import { createExtensionUnitTestingServices } from '../../../test/node/services';9import { McpSetupCommands } from '../../vscode-node/commands';10import { FixtureFetcherService } from './util';1112describe('get MCP server info', { timeout: 30_000 }, () => {13let testingServiceCollection: TestingServiceCollection;14let accessor: ITestingServicesAccessor;15let logService: ILogService;16let emptyFetcherService: FixtureFetcherService;1718beforeEach(() => {19testingServiceCollection = createExtensionUnitTestingServices();20accessor = testingServiceCollection.createTestingAccessor();21logService = accessor.get(ILogService);22emptyFetcherService = new FixtureFetcherService();23});2425it('npm returns package metadata', async () => {26const fetcherService = new FixtureFetcherService(new Map([27['https://registry.npmjs.org/%40modelcontextprotocol%2Fserver-everything', {28fileName: 'npm-modelcontextprotocol-server-everything.json',29status: 20030}]31]));32const result = await McpSetupCommands.validatePackageRegistry({ type: 'npm', name: '@modelcontextprotocol/server-everything' }, logService, fetcherService);33expect(result.state).toBe('ok');34if (result.state === 'ok') {35expect(result.name).toBe('@modelcontextprotocol/server-everything');36expect(result.version).toBeDefined();37expect(result.publisher).toContain('jspahrsummers');38} else {39expect.fail();40}41});4243it('npm handles missing package', async () => {44const result = await McpSetupCommands.validatePackageRegistry({ type: 'npm', name: '@modelcontextprotocol/does-not-exist' }, logService, emptyFetcherService);45expect(emptyFetcherService.urls[0]).toBe('https://registry.npmjs.org/%40modelcontextprotocol%2Fdoes-not-exist');46expect(result.state).toBe('error');47if (result.state === 'error') {48expect(result.error).toBeDefined();49expect(result.errorType).toBe('NotFound');50} else {51expect.fail();52}53});5455it('pip returns package metadata', async () => {56const fetcherService = new FixtureFetcherService(new Map([57['https://pypi.org/pypi/mcp-server-fetch/json', {58fileName: 'pip-mcp-server-fetch.json',59status: 20060}]61]));62const result = await McpSetupCommands.validatePackageRegistry({ type: 'pip', name: 'mcp-server-fetch' }, logService, fetcherService);63expect(result.state).toBe('ok');64if (result.state === 'ok') {65expect(result.name).toBe('mcp-server-fetch');66expect(result.version).toBeDefined();67expect(result.publisher).toContain('Anthropic');68} else {69expect.fail();70}71});7273it('pip handles missing package', async () => {74const result = await McpSetupCommands.validatePackageRegistry({ type: 'pip', name: 'mcp-server-that-does-not-exist' }, logService, emptyFetcherService);75expect(emptyFetcherService.urls[0]).toBe('https://pypi.org/pypi/mcp-server-that-does-not-exist/json');76expect(result.state).toBe('error');77if (result.state === 'error') {78expect(result.error).toBeDefined();79expect(result.errorType).toBe('NotFound');80} else {81expect.fail();82}83});8485it('docker returns package metadata', async () => {86const fetcherService = new FixtureFetcherService(new Map([87['https://hub.docker.com/v2/repositories/mcp/node-code-sandbox', {88fileName: 'docker-mcp-node-code-sandbox.json',89status: 20090}]91]));92const result = await McpSetupCommands.validatePackageRegistry({ type: 'docker', name: 'mcp/node-code-sandbox' }, logService, fetcherService);93expect(result.state).toBe('ok');94if (result.state === 'ok') {95expect(result.name).toBe('mcp/node-code-sandbox');96expect(result.version).toBeUndefined(); // currently not populated97expect(result.publisher).toBe('mcp');98} else {99expect.fail();100}101});102103it('docker handles missing package', async () => {104const result = await McpSetupCommands.validatePackageRegistry({ type: 'docker', name: 'mcp/server-that-does-not-exist' }, logService, emptyFetcherService);105expect(emptyFetcherService.urls[0]).toBe('https://hub.docker.com/v2/repositories/mcp/server-that-does-not-exist');106expect(result.state).toBe('error');107if (result.state === 'error') {108expect(result.error).toBeDefined();109expect(result.errorType).toBe('NotFound');110} else {111expect.fail();112}113});114});115116117