Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/copilot/src/extension/mcp/test/vscode-node/nuget.integration.spec.ts
13405 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import path from 'path';
7
import { beforeEach, describe, expect, it } from 'vitest';
8
import { ILogService } from '../../../../platform/log/common/logService';
9
import { IFetcherService } from '../../../../platform/networking/common/fetcherService';
10
import { ITestingServicesAccessor, TestingServiceCollection } from '../../../../platform/test/node/services';
11
import { createExtensionUnitTestingServices } from '../../../test/node/services';
12
import { IMcpStdioServerConfiguration, NuGetMcpSetup } from '../../vscode-node/nuget';
13
import { CommandExecutor, ICommandExecutor } from '../../vscode-node/util';
14
import { FixtureFetcherService } from './util';
15
16
const RUN_DOTNET_CLI_TESTS = !!process.env['CI'] && !process.env['BUILD_ARTIFACTSTAGINGDIRECTORY'];
17
18
describe.runIf(RUN_DOTNET_CLI_TESTS).skip('get nuget MCP server info using dotnet CLI', { timeout: 30_000 }, () => {
19
let testingServiceCollection: TestingServiceCollection;
20
let accessor: ITestingServicesAccessor;
21
let logService: ILogService;
22
let fetcherService: IFetcherService;
23
let commandExecutor: ICommandExecutor;
24
let nuget: NuGetMcpSetup;
25
26
beforeEach(() => {
27
testingServiceCollection = createExtensionUnitTestingServices();
28
accessor = testingServiceCollection.createTestingAccessor();
29
logService = accessor.get(ILogService);
30
fetcherService = new FixtureFetcherService();
31
commandExecutor = new CommandExecutor();
32
nuget = new NuGetMcpSetup(
33
logService,
34
fetcherService,
35
commandExecutor,
36
{ command: 'dotnet', args: [] }, // allow dotnet command to be overridden for testing
37
path.join(__dirname, 'fixtures', 'nuget') // file based package source for testing
38
);
39
});
40
41
it('returns mapped server.json for original schema', async () => {
42
const result = await nuget.getNuGetPackageMetadata('Knapcode.SampleMcpServer');
43
expect(result.state).toBe('ok');
44
if (result.state === 'ok') {
45
expect(result.getMcpServer).toBeDefined();
46
if (result.getMcpServer) {
47
const mcpServer = await result.getMcpServer(Promise.resolve());
48
expect(mcpServer).toBeDefined();
49
const config = mcpServer!.config as Omit<IMcpStdioServerConfiguration, 'type'>;
50
expect(config.command).toBe('dnx');
51
expect(config.env).toEqual({ 'WEATHER_CHOICES': '${input:weather_choices}' });
52
expect(config.args).toEqual(['[email protected]', '--yes', '--', 'mcp', 'start']);
53
} else {
54
expect.fail();
55
}
56
} else {
57
expect.fail();
58
}
59
});
60
61
it('returns mapped server.json for 2025-09-29 schema', async () => {
62
const result = await nuget.getNuGetPackageMetadata('BaseTestPackage.McpServer');
63
expect(result.state).toBe('ok');
64
if (result.state === 'ok') {
65
expect(result.getMcpServer).toBeDefined();
66
if (result.getMcpServer) {
67
const mcpServer = await result.getMcpServer(Promise.resolve());
68
expect(mcpServer).toBeDefined();
69
const config = mcpServer!.config as Omit<IMcpStdioServerConfiguration, 'type'>;
70
expect(config.command).toBe('dnx');
71
expect(config.env).toEqual({ 'WEATHER_CHOICES': '${input:weather_choices}' });
72
expect(config.args).toEqual(['[email protected]', '--yes', '--', 'mcp', 'start']);
73
} else {
74
expect.fail();
75
}
76
} else {
77
expect.fail();
78
}
79
});
80
81
it('returns package metadata', async () => {
82
const result = await nuget.getNuGetPackageMetadata('basetestpackage.dotnettool');
83
expect(result.state).toBe('ok');
84
if (result.state === 'ok') {
85
expect(result.name).toBe('BaseTestPackage.DotnetTool');
86
expect(result.version).toBe('1.0.0');
87
} else {
88
expect.fail();
89
}
90
});
91
92
it('handles missing package', async () => {
93
const result = await nuget.getNuGetPackageMetadata('BaseTestPackage.DoesNotExist');
94
expect(result.state).toBe('error');
95
if (result.state === 'error') {
96
expect(result.error).toBeDefined();
97
expect(result.errorType).toBe('NotFound');
98
} else {
99
expect.fail();
100
}
101
});
102
103
it('handles missing dotnet', async () => {
104
nuget.dotnet.command = 'dotnet-missing';
105
const result = await nuget.getNuGetPackageMetadata('Knapcode.SampleMcpServer');
106
expect(result.state).toBe('error');
107
if (result.state === 'error') {
108
expect(result.errorType).toBe('MissingCommand');
109
expect(result.helpUriLabel).toBe('Install .NET SDK');
110
expect(result.helpUri).toBe('https://aka.ms/vscode-mcp-install/dotnet');
111
} else {
112
expect.fail();
113
}
114
});
115
116
it('handles old dotnet version', async () => {
117
nuget.dotnet.command = 'node';
118
nuget.dotnet.args = ['-e', 'console.log("9.0.0")', '--'];
119
const result = await nuget.getNuGetPackageMetadata('Knapcode.SampleMcpServer');
120
expect(result.state).toBe('error');
121
if (result.state === 'error') {
122
expect(result.errorType).toBe('BadCommandVersion');
123
expect(result.helpUriLabel).toBe('Update .NET SDK');
124
expect(result.helpUri).toBe('https://aka.ms/vscode-mcp-install/dotnet');
125
} else {
126
expect.fail();
127
}
128
});
129
});
130
131