Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/api/test/browser/mainThreadAuthentication.integrationTest.ts
3296 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 assert from 'assert';
7
import { IDialogService } from '../../../../platform/dialogs/common/dialogs.js';
8
import { TestDialogService } from '../../../../platform/dialogs/test/common/testDialogService.js';
9
import { TestInstantiationService } from '../../../../platform/instantiation/test/common/instantiationServiceMock.js';
10
import { INotificationService } from '../../../../platform/notification/common/notification.js';
11
import { TestNotificationService } from '../../../../platform/notification/test/common/testNotificationService.js';
12
import { IQuickInputService } from '../../../../platform/quickinput/common/quickInput.js';
13
import { IStorageService } from '../../../../platform/storage/common/storage.js';
14
import { ITelemetryService } from '../../../../platform/telemetry/common/telemetry.js';
15
import { NullTelemetryService } from '../../../../platform/telemetry/common/telemetryUtils.js';
16
import { MainThreadAuthentication } from '../../browser/mainThreadAuthentication.js';
17
import { ExtHostContext, MainContext } from '../../common/extHost.protocol.js';
18
import { IActivityService } from '../../../services/activity/common/activity.js';
19
import { AuthenticationService } from '../../../services/authentication/browser/authenticationService.js';
20
import { IAuthenticationExtensionsService, IAuthenticationService } from '../../../services/authentication/common/authentication.js';
21
import { IExtensionService } from '../../../services/extensions/common/extensions.js';
22
import { IRemoteAgentService } from '../../../services/remote/common/remoteAgentService.js';
23
import { TestRPCProtocol } from '../common/testRPCProtocol.js';
24
import { TestEnvironmentService, TestHostService, TestQuickInputService, TestRemoteAgentService } from '../../../test/browser/workbenchTestServices.js';
25
import { TestActivityService, TestExtensionService, TestProductService, TestStorageService } from '../../../test/common/workbenchTestServices.js';
26
import { IBrowserWorkbenchEnvironmentService } from '../../../services/environment/browser/environmentService.js';
27
import { IProductService } from '../../../../platform/product/common/productService.js';
28
import { AuthenticationAccessService, IAuthenticationAccessService } from '../../../services/authentication/browser/authenticationAccessService.js';
29
import { IAccountUsage, IAuthenticationUsageService } from '../../../services/authentication/browser/authenticationUsageService.js';
30
import { AuthenticationExtensionsService } from '../../../services/authentication/browser/authenticationExtensionsService.js';
31
import { ILogService, NullLogService } from '../../../../platform/log/common/log.js';
32
import { IHostService } from '../../../services/host/browser/host.js';
33
import { IOpenerService } from '../../../../platform/opener/common/opener.js';
34
import { IUserActivityService, UserActivityService } from '../../../services/userActivity/common/userActivityService.js';
35
import { ISecretStorageService } from '../../../../platform/secrets/common/secrets.js';
36
import { TestSecretStorageService } from '../../../../platform/secrets/test/common/testSecretStorageService.js';
37
import { IDynamicAuthenticationProviderStorageService } from '../../../services/authentication/common/dynamicAuthenticationProviderStorage.js';
38
import { DynamicAuthenticationProviderStorageService } from '../../../services/authentication/browser/dynamicAuthenticationProviderStorageService.js';
39
import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../base/test/common/utils.js';
40
import { ServiceCollection } from '../../../../platform/instantiation/common/serviceCollection.js';
41
import { SyncDescriptor } from '../../../../platform/instantiation/common/descriptors.js';
42
43
class TestAuthUsageService implements IAuthenticationUsageService {
44
_serviceBrand: undefined;
45
initializeExtensionUsageCache(): Promise<void> { return Promise.resolve(); }
46
extensionUsesAuth(extensionId: string): Promise<boolean> { return Promise.resolve(false); }
47
readAccountUsages(providerId: string, accountName: string): IAccountUsage[] { return []; }
48
removeAccountUsage(providerId: string, accountName: string): void { }
49
addAccountUsage(providerId: string, accountName: string, scopes: ReadonlyArray<string>, extensionId: string, extensionName: string): void { }
50
}
51
52
suite('MainThreadAuthentication', () => {
53
const disposables = ensureNoDisposablesAreLeakedInTestSuite();
54
55
let mainThreadAuthentication: MainThreadAuthentication;
56
let instantiationService: TestInstantiationService;
57
let rpcProtocol: TestRPCProtocol;
58
59
setup(async () => {
60
// services
61
const services = new ServiceCollection();
62
services.set(ILogService, new SyncDescriptor(NullLogService));
63
services.set(IDialogService, new SyncDescriptor(TestDialogService, [{ confirmed: true }]));
64
services.set(IStorageService, new SyncDescriptor(TestStorageService));
65
services.set(ISecretStorageService, new SyncDescriptor(TestSecretStorageService));
66
services.set(IDynamicAuthenticationProviderStorageService, new SyncDescriptor(DynamicAuthenticationProviderStorageService));
67
services.set(IQuickInputService, new SyncDescriptor(TestQuickInputService));
68
services.set(IExtensionService, new SyncDescriptor(TestExtensionService));
69
services.set(IActivityService, new SyncDescriptor(TestActivityService));
70
services.set(IRemoteAgentService, new SyncDescriptor(TestRemoteAgentService));
71
services.set(INotificationService, new SyncDescriptor(TestNotificationService));
72
services.set(IHostService, new SyncDescriptor(TestHostService));
73
services.set(IUserActivityService, new SyncDescriptor(UserActivityService));
74
services.set(IAuthenticationAccessService, new SyncDescriptor(AuthenticationAccessService));
75
services.set(IAuthenticationService, new SyncDescriptor(AuthenticationService));
76
services.set(IAuthenticationUsageService, new SyncDescriptor(TestAuthUsageService));
77
services.set(IAuthenticationExtensionsService, new SyncDescriptor(AuthenticationExtensionsService));
78
instantiationService = disposables.add(new TestInstantiationService(services, undefined, undefined, true));
79
80
// stubs
81
// eslint-disable-next-line local/code-no-dangerous-type-assertions
82
instantiationService.stub(IOpenerService, {} as Partial<IOpenerService>);
83
instantiationService.stub(ITelemetryService, NullTelemetryService);
84
instantiationService.stub(IBrowserWorkbenchEnvironmentService, TestEnvironmentService);
85
instantiationService.stub(IProductService, TestProductService);
86
87
rpcProtocol = disposables.add(new TestRPCProtocol());
88
mainThreadAuthentication = disposables.add(instantiationService.createInstance(MainThreadAuthentication, rpcProtocol));
89
rpcProtocol.set(MainContext.MainThreadAuthentication, mainThreadAuthentication);
90
});
91
92
test('provider registration completes without errors', async () => {
93
// Test basic registration - this should complete without throwing
94
await mainThreadAuthentication.$registerAuthenticationProvider('test-provider', 'Test Provider', false);
95
96
// Test unregistration - this should also complete without throwing
97
await mainThreadAuthentication.$unregisterAuthenticationProvider('test-provider');
98
99
// Success if we reach here without timeout
100
assert.ok(true, 'Registration and unregistration completed successfully');
101
});
102
103
test('event suppression during explicit unregistration', async () => {
104
let unregisterEventFired = false;
105
let eventProviderId: string | undefined;
106
107
// Mock the ext host to capture unregister events
108
const mockExtHost = {
109
$onDidUnregisterAuthenticationProvider: (id: string) => {
110
unregisterEventFired = true;
111
eventProviderId = id;
112
return Promise.resolve();
113
},
114
$getSessions: () => Promise.resolve([]),
115
$createSession: () => Promise.resolve({} as any),
116
$removeSession: () => Promise.resolve(),
117
$onDidChangeAuthenticationSessions: () => Promise.resolve(),
118
$registerDynamicAuthProvider: () => Promise.resolve('test'),
119
$onDidChangeDynamicAuthProviderTokens: () => Promise.resolve(),
120
$getSessionsFromChallenges: () => Promise.resolve([]),
121
$createSessionFromChallenges: () => Promise.resolve({} as any),
122
};
123
rpcProtocol.set(ExtHostContext.ExtHostAuthentication, mockExtHost);
124
125
// Register a provider
126
await mainThreadAuthentication.$registerAuthenticationProvider('test-suppress', 'Test Suppress', false);
127
128
// Reset the flag
129
unregisterEventFired = false;
130
eventProviderId = undefined;
131
132
// Unregister the provider - this should NOT fire the event due to suppression
133
await mainThreadAuthentication.$unregisterAuthenticationProvider('test-suppress');
134
135
// Verify the event was suppressed
136
assert.strictEqual(unregisterEventFired, false, 'Unregister event should be suppressed during explicit unregistration');
137
assert.strictEqual(eventProviderId, undefined, 'No provider ID should be captured from suppressed event');
138
});
139
140
test('concurrent provider registrations complete without errors', async () => {
141
// Register multiple providers simultaneously
142
const registrationPromises = [
143
mainThreadAuthentication.$registerAuthenticationProvider('concurrent-1', 'Concurrent 1', false),
144
mainThreadAuthentication.$registerAuthenticationProvider('concurrent-2', 'Concurrent 2', false),
145
mainThreadAuthentication.$registerAuthenticationProvider('concurrent-3', 'Concurrent 3', false)
146
];
147
148
await Promise.all(registrationPromises);
149
150
// Unregister all providers
151
const unregistrationPromises = [
152
mainThreadAuthentication.$unregisterAuthenticationProvider('concurrent-1'),
153
mainThreadAuthentication.$unregisterAuthenticationProvider('concurrent-2'),
154
mainThreadAuthentication.$unregisterAuthenticationProvider('concurrent-3')
155
];
156
157
await Promise.all(unregistrationPromises);
158
159
// Success if we reach here without timeout
160
assert.ok(true, 'Concurrent registrations and unregistrations completed successfully');
161
});
162
});
163
164