Skip to content

Commit 6a30aa6

Browse files
author
William Stuckey
committed
Add regression tests for MCP registry data preservation on transient failure
1 parent 8f6712e commit 6a30aa6

1 file changed

Lines changed: 90 additions & 1 deletion

File tree

src/vs/workbench/services/accounts/test/browser/defaultAccount.test.ts

Lines changed: 90 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,95 @@ suite('DefaultAccountProvider managed settings', () => {
201201
});
202202
});
203203

204-
async function createProvider(requestService: TestRequestService): Promise<DefaultAccountProvider> {
204+
test('transient MCP registry failure preserves cached enterprise registry data', async () => {
205+
const requestService = new TestRequestService(async options => {
206+
if (options.url?.endsWith('/copilot_internal/user')) {
207+
return jsonResponse({ chat_enabled: true });
208+
}
209+
if (options.url?.endsWith('/copilot_internal/v2/token')) {
210+
return jsonResponse({ token: 'mcp=1' });
211+
}
212+
if (options.url?.includes('/copilot/mcp_registry')) {
213+
// 5xx is a transient failure: enterprise registry data must be preserved.
214+
return jsonResponse({}, 500);
215+
}
216+
throw new Error(`Unexpected request: ${options.url}`);
217+
});
218+
const provider = await createProvider(requestService, {
219+
tokenEntitlementUrl: 'https://api.github.com/copilot_internal/v2/token',
220+
mcpRegistryDataUrl: 'https://api.github.com/copilot/mcp_registry',
221+
managedSettingsUrl: '',
222+
});
223+
provider['_policyData'] = {
224+
accountId,
225+
policyData: {
226+
mcp: true,
227+
mcpRegistryUrl: 'https://example.com/enterprise-registry',
228+
mcpAccess: 'registry_only',
229+
},
230+
mcpRegistryDataFetchedAt: Date.now(),
231+
};
232+
233+
const result = await provider['getDefaultAccountFromAuthenticatedSessions'](
234+
{ id: 'github', name: 'GitHub', enterprise: false },
235+
sessions,
236+
{ forceRefresh: true }
237+
);
238+
239+
assert.deepStrictEqual({
240+
mcpRegistryUrl: result?.policyData?.policyData.mcpRegistryUrl,
241+
mcpAccess: result?.policyData?.policyData.mcpAccess,
242+
}, {
243+
mcpRegistryUrl: 'https://example.com/enterprise-registry',
244+
mcpAccess: 'registry_only',
245+
});
246+
});
247+
248+
test('definitive MCP registry removal clears cached registry data', async () => {
249+
const requestService = new TestRequestService(async options => {
250+
if (options.url?.endsWith('/copilot_internal/user')) {
251+
return jsonResponse({ chat_enabled: true });
252+
}
253+
if (options.url?.endsWith('/copilot_internal/v2/token')) {
254+
return jsonResponse({ token: 'mcp=1' });
255+
}
256+
if (options.url?.includes('/copilot/mcp_registry')) {
257+
// 4xx is a definitive "no registry available" signal: cached data must be cleared.
258+
return jsonResponse({}, 404);
259+
}
260+
throw new Error(`Unexpected request: ${options.url}`);
261+
});
262+
const provider = await createProvider(requestService, {
263+
tokenEntitlementUrl: 'https://api.github.com/copilot_internal/v2/token',
264+
mcpRegistryDataUrl: 'https://api.github.com/copilot/mcp_registry',
265+
managedSettingsUrl: '',
266+
});
267+
provider['_policyData'] = {
268+
accountId,
269+
policyData: {
270+
mcp: true,
271+
mcpRegistryUrl: 'https://example.com/enterprise-registry',
272+
mcpAccess: 'registry_only',
273+
},
274+
mcpRegistryDataFetchedAt: Date.now(),
275+
};
276+
277+
const result = await provider['getDefaultAccountFromAuthenticatedSessions'](
278+
{ id: 'github', name: 'GitHub', enterprise: false },
279+
sessions,
280+
{ forceRefresh: true }
281+
);
282+
283+
assert.deepStrictEqual({
284+
mcpRegistryUrl: result?.policyData?.policyData.mcpRegistryUrl,
285+
mcpAccess: result?.policyData?.policyData.mcpAccess,
286+
}, {
287+
mcpRegistryUrl: undefined,
288+
mcpAccess: undefined,
289+
});
290+
});
291+
292+
async function createProvider(requestService: TestRequestService, configOverrides?: Partial<{ tokenEntitlementUrl: string; mcpRegistryDataUrl: string; managedSettingsUrl: string }>): Promise<DefaultAccountProvider> {
205293
const instantiationService = disposables.add(new TestInstantiationService());
206294
instantiationService.stub(IConfigurationService, new TestConfigurationService());
207295
instantiationService.stub(IAuthenticationService, {
@@ -252,6 +340,7 @@ suite('DefaultAccountProvider managed settings', () => {
252340
entitlementUrl: 'https://api.github.com/copilot_internal/user',
253341
mcpRegistryDataUrl: '',
254342
managedSettingsUrl: 'https://api.github.com/copilot_internal/managed_settings',
343+
...configOverrides,
255344
}));
256345
await provider.refresh();
257346
return provider;

0 commit comments

Comments
 (0)