Path: blob/main/src/vs/workbench/api/test/browser/mainThreadAuthentication.integrationTest.ts
3296 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 assert from 'assert';6import { IDialogService } from '../../../../platform/dialogs/common/dialogs.js';7import { TestDialogService } from '../../../../platform/dialogs/test/common/testDialogService.js';8import { TestInstantiationService } from '../../../../platform/instantiation/test/common/instantiationServiceMock.js';9import { INotificationService } from '../../../../platform/notification/common/notification.js';10import { TestNotificationService } from '../../../../platform/notification/test/common/testNotificationService.js';11import { IQuickInputService } from '../../../../platform/quickinput/common/quickInput.js';12import { IStorageService } from '../../../../platform/storage/common/storage.js';13import { ITelemetryService } from '../../../../platform/telemetry/common/telemetry.js';14import { NullTelemetryService } from '../../../../platform/telemetry/common/telemetryUtils.js';15import { MainThreadAuthentication } from '../../browser/mainThreadAuthentication.js';16import { ExtHostContext, MainContext } from '../../common/extHost.protocol.js';17import { IActivityService } from '../../../services/activity/common/activity.js';18import { AuthenticationService } from '../../../services/authentication/browser/authenticationService.js';19import { IAuthenticationExtensionsService, IAuthenticationService } from '../../../services/authentication/common/authentication.js';20import { IExtensionService } from '../../../services/extensions/common/extensions.js';21import { IRemoteAgentService } from '../../../services/remote/common/remoteAgentService.js';22import { TestRPCProtocol } from '../common/testRPCProtocol.js';23import { TestEnvironmentService, TestHostService, TestQuickInputService, TestRemoteAgentService } from '../../../test/browser/workbenchTestServices.js';24import { TestActivityService, TestExtensionService, TestProductService, TestStorageService } from '../../../test/common/workbenchTestServices.js';25import { IBrowserWorkbenchEnvironmentService } from '../../../services/environment/browser/environmentService.js';26import { IProductService } from '../../../../platform/product/common/productService.js';27import { AuthenticationAccessService, IAuthenticationAccessService } from '../../../services/authentication/browser/authenticationAccessService.js';28import { IAccountUsage, IAuthenticationUsageService } from '../../../services/authentication/browser/authenticationUsageService.js';29import { AuthenticationExtensionsService } from '../../../services/authentication/browser/authenticationExtensionsService.js';30import { ILogService, NullLogService } from '../../../../platform/log/common/log.js';31import { IHostService } from '../../../services/host/browser/host.js';32import { IOpenerService } from '../../../../platform/opener/common/opener.js';33import { IUserActivityService, UserActivityService } from '../../../services/userActivity/common/userActivityService.js';34import { ISecretStorageService } from '../../../../platform/secrets/common/secrets.js';35import { TestSecretStorageService } from '../../../../platform/secrets/test/common/testSecretStorageService.js';36import { IDynamicAuthenticationProviderStorageService } from '../../../services/authentication/common/dynamicAuthenticationProviderStorage.js';37import { DynamicAuthenticationProviderStorageService } from '../../../services/authentication/browser/dynamicAuthenticationProviderStorageService.js';38import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../base/test/common/utils.js';39import { ServiceCollection } from '../../../../platform/instantiation/common/serviceCollection.js';40import { SyncDescriptor } from '../../../../platform/instantiation/common/descriptors.js';4142class TestAuthUsageService implements IAuthenticationUsageService {43_serviceBrand: undefined;44initializeExtensionUsageCache(): Promise<void> { return Promise.resolve(); }45extensionUsesAuth(extensionId: string): Promise<boolean> { return Promise.resolve(false); }46readAccountUsages(providerId: string, accountName: string): IAccountUsage[] { return []; }47removeAccountUsage(providerId: string, accountName: string): void { }48addAccountUsage(providerId: string, accountName: string, scopes: ReadonlyArray<string>, extensionId: string, extensionName: string): void { }49}5051suite('MainThreadAuthentication', () => {52const disposables = ensureNoDisposablesAreLeakedInTestSuite();5354let mainThreadAuthentication: MainThreadAuthentication;55let instantiationService: TestInstantiationService;56let rpcProtocol: TestRPCProtocol;5758setup(async () => {59// services60const services = new ServiceCollection();61services.set(ILogService, new SyncDescriptor(NullLogService));62services.set(IDialogService, new SyncDescriptor(TestDialogService, [{ confirmed: true }]));63services.set(IStorageService, new SyncDescriptor(TestStorageService));64services.set(ISecretStorageService, new SyncDescriptor(TestSecretStorageService));65services.set(IDynamicAuthenticationProviderStorageService, new SyncDescriptor(DynamicAuthenticationProviderStorageService));66services.set(IQuickInputService, new SyncDescriptor(TestQuickInputService));67services.set(IExtensionService, new SyncDescriptor(TestExtensionService));68services.set(IActivityService, new SyncDescriptor(TestActivityService));69services.set(IRemoteAgentService, new SyncDescriptor(TestRemoteAgentService));70services.set(INotificationService, new SyncDescriptor(TestNotificationService));71services.set(IHostService, new SyncDescriptor(TestHostService));72services.set(IUserActivityService, new SyncDescriptor(UserActivityService));73services.set(IAuthenticationAccessService, new SyncDescriptor(AuthenticationAccessService));74services.set(IAuthenticationService, new SyncDescriptor(AuthenticationService));75services.set(IAuthenticationUsageService, new SyncDescriptor(TestAuthUsageService));76services.set(IAuthenticationExtensionsService, new SyncDescriptor(AuthenticationExtensionsService));77instantiationService = disposables.add(new TestInstantiationService(services, undefined, undefined, true));7879// stubs80// eslint-disable-next-line local/code-no-dangerous-type-assertions81instantiationService.stub(IOpenerService, {} as Partial<IOpenerService>);82instantiationService.stub(ITelemetryService, NullTelemetryService);83instantiationService.stub(IBrowserWorkbenchEnvironmentService, TestEnvironmentService);84instantiationService.stub(IProductService, TestProductService);8586rpcProtocol = disposables.add(new TestRPCProtocol());87mainThreadAuthentication = disposables.add(instantiationService.createInstance(MainThreadAuthentication, rpcProtocol));88rpcProtocol.set(MainContext.MainThreadAuthentication, mainThreadAuthentication);89});9091test('provider registration completes without errors', async () => {92// Test basic registration - this should complete without throwing93await mainThreadAuthentication.$registerAuthenticationProvider('test-provider', 'Test Provider', false);9495// Test unregistration - this should also complete without throwing96await mainThreadAuthentication.$unregisterAuthenticationProvider('test-provider');9798// Success if we reach here without timeout99assert.ok(true, 'Registration and unregistration completed successfully');100});101102test('event suppression during explicit unregistration', async () => {103let unregisterEventFired = false;104let eventProviderId: string | undefined;105106// Mock the ext host to capture unregister events107const mockExtHost = {108$onDidUnregisterAuthenticationProvider: (id: string) => {109unregisterEventFired = true;110eventProviderId = id;111return Promise.resolve();112},113$getSessions: () => Promise.resolve([]),114$createSession: () => Promise.resolve({} as any),115$removeSession: () => Promise.resolve(),116$onDidChangeAuthenticationSessions: () => Promise.resolve(),117$registerDynamicAuthProvider: () => Promise.resolve('test'),118$onDidChangeDynamicAuthProviderTokens: () => Promise.resolve(),119$getSessionsFromChallenges: () => Promise.resolve([]),120$createSessionFromChallenges: () => Promise.resolve({} as any),121};122rpcProtocol.set(ExtHostContext.ExtHostAuthentication, mockExtHost);123124// Register a provider125await mainThreadAuthentication.$registerAuthenticationProvider('test-suppress', 'Test Suppress', false);126127// Reset the flag128unregisterEventFired = false;129eventProviderId = undefined;130131// Unregister the provider - this should NOT fire the event due to suppression132await mainThreadAuthentication.$unregisterAuthenticationProvider('test-suppress');133134// Verify the event was suppressed135assert.strictEqual(unregisterEventFired, false, 'Unregister event should be suppressed during explicit unregistration');136assert.strictEqual(eventProviderId, undefined, 'No provider ID should be captured from suppressed event');137});138139test('concurrent provider registrations complete without errors', async () => {140// Register multiple providers simultaneously141const registrationPromises = [142mainThreadAuthentication.$registerAuthenticationProvider('concurrent-1', 'Concurrent 1', false),143mainThreadAuthentication.$registerAuthenticationProvider('concurrent-2', 'Concurrent 2', false),144mainThreadAuthentication.$registerAuthenticationProvider('concurrent-3', 'Concurrent 3', false)145];146147await Promise.all(registrationPromises);148149// Unregister all providers150const unregistrationPromises = [151mainThreadAuthentication.$unregisterAuthenticationProvider('concurrent-1'),152mainThreadAuthentication.$unregisterAuthenticationProvider('concurrent-2'),153mainThreadAuthentication.$unregisterAuthenticationProvider('concurrent-3')154];155156await Promise.all(unregistrationPromises);157158// Success if we reach here without timeout159assert.ok(true, 'Concurrent registrations and unregistrations completed successfully');160});161});162163164