Path: blob/main/src/vs/workbench/services/authentication/test/browser/authenticationService.test.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 { Emitter, Event } from '../../../../../base/common/event.js';7import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../../base/test/common/utils.js';8import { URI } from '../../../../../base/common/uri.js';9import { AuthenticationAccessService } from '../../browser/authenticationAccessService.js';10import { AuthenticationService } from '../../browser/authenticationService.js';11import { AuthenticationProviderInformation, AuthenticationSessionsChangeEvent, IAuthenticationProvider } from '../../common/authentication.js';12import { TestEnvironmentService } from '../../../../test/browser/workbenchTestServices.js';13import { TestExtensionService, TestProductService, TestStorageService } from '../../../../test/common/workbenchTestServices.js';14import { NullLogService } from '../../../../../platform/log/common/log.js';1516function createSession() {17return { id: 'session1', accessToken: 'token1', account: { id: 'account', label: 'Account' }, scopes: ['test'] };18}1920function createProvider(overrides: Partial<IAuthenticationProvider> = {}): IAuthenticationProvider {21return {22supportsMultipleAccounts: false,23onDidChangeSessions: new Emitter<AuthenticationSessionsChangeEvent>().event,24id: 'test',25label: 'Test',26getSessions: async () => [],27createSession: async () => createSession(),28removeSession: async () => { },29...overrides30};31}3233suite('AuthenticationService', () => {34const disposables = ensureNoDisposablesAreLeakedInTestSuite();3536let authenticationService: AuthenticationService;3738setup(() => {39const storageService = disposables.add(new TestStorageService());40const authenticationAccessService = disposables.add(new AuthenticationAccessService(storageService, TestProductService));41authenticationService = disposables.add(new AuthenticationService(new TestExtensionService(), authenticationAccessService, TestEnvironmentService, new NullLogService()));42});4344teardown(() => {45// Dispose the authentication service after each test46authenticationService.dispose();47});4849suite('declaredAuthenticationProviders', () => {50test('registerDeclaredAuthenticationProvider', async () => {51const changed = Event.toPromise(authenticationService.onDidChangeDeclaredProviders);52const provider: AuthenticationProviderInformation = {53id: 'github',54label: 'GitHub'55};56authenticationService.registerDeclaredAuthenticationProvider(provider);5758// Assert that the provider is added to the declaredProviders array and the event fires59assert.equal(authenticationService.declaredProviders.length, 1);60assert.deepEqual(authenticationService.declaredProviders[0], provider);61await changed;62});6364test('unregisterDeclaredAuthenticationProvider', async () => {65const provider: AuthenticationProviderInformation = {66id: 'github',67label: 'GitHub'68};69authenticationService.registerDeclaredAuthenticationProvider(provider);70const changed = Event.toPromise(authenticationService.onDidChangeDeclaredProviders);71authenticationService.unregisterDeclaredAuthenticationProvider(provider.id);7273// Assert that the provider is removed from the declaredProviders array and the event fires74assert.equal(authenticationService.declaredProviders.length, 0);75await changed;76});77});7879suite('authenticationProviders', () => {80test('isAuthenticationProviderRegistered', async () => {81const registered = Event.toPromise(authenticationService.onDidRegisterAuthenticationProvider);82const provider = createProvider();83assert.equal(authenticationService.isAuthenticationProviderRegistered(provider.id), false);84authenticationService.registerAuthenticationProvider(provider.id, provider);85assert.equal(authenticationService.isAuthenticationProviderRegistered(provider.id), true);86const result = await registered;87assert.deepEqual(result, { id: provider.id, label: provider.label });88});8990test('unregisterAuthenticationProvider', async () => {91const unregistered = Event.toPromise(authenticationService.onDidUnregisterAuthenticationProvider);92const provider = createProvider();93authenticationService.registerAuthenticationProvider(provider.id, provider);94assert.equal(authenticationService.isAuthenticationProviderRegistered(provider.id), true);95authenticationService.unregisterAuthenticationProvider(provider.id);96assert.equal(authenticationService.isAuthenticationProviderRegistered(provider.id), false);97const result = await unregistered;98assert.deepEqual(result, { id: provider.id, label: provider.label });99});100101test('getProviderIds', () => {102const provider1 = createProvider({103id: 'provider1',104label: 'Provider 1'105});106const provider2 = createProvider({107id: 'provider2',108label: 'Provider 2'109});110111authenticationService.registerAuthenticationProvider(provider1.id, provider1);112authenticationService.registerAuthenticationProvider(provider2.id, provider2);113114const providerIds = authenticationService.getProviderIds();115116// Assert that the providerIds array contains the registered provider ids117assert.deepEqual(providerIds, [provider1.id, provider2.id]);118});119120test('getProvider', () => {121const provider = createProvider();122123authenticationService.registerAuthenticationProvider(provider.id, provider);124125const retrievedProvider = authenticationService.getProvider(provider.id);126127// Assert that the retrieved provider is the same as the registered provider128assert.deepEqual(retrievedProvider, provider);129});130131test('getOrActivateProviderIdForServer - should return undefined when no provider matches the authorization server', async () => {132const authorizationServer = URI.parse('https://example.com');133const result = await authenticationService.getOrActivateProviderIdForServer(authorizationServer);134assert.strictEqual(result, undefined);135});136137test('getOrActivateProviderIdForServer - should return provider id if authorizationServerGlobs matches and authorizationServers match', async () => {138// Register a declared provider with an authorization server glob139const provider: AuthenticationProviderInformation = {140id: 'github',141label: 'GitHub',142authorizationServerGlobs: ['https://github.com/*']143};144authenticationService.registerDeclaredAuthenticationProvider(provider);145146// Register an authentication provider with matching authorization servers147const authProvider = createProvider({148id: 'github',149label: 'GitHub',150authorizationServers: [URI.parse('https://github.com/login')]151});152authenticationService.registerAuthenticationProvider('github', authProvider);153154// Test with a matching URI155const authorizationServer = URI.parse('https://github.com/login');156const result = await authenticationService.getOrActivateProviderIdForServer(authorizationServer);157158// Verify the result159assert.strictEqual(result, 'github');160});161162test('getOrActivateProviderIdForServer - should return undefined if authorizationServerGlobs match but authorizationServers do not match', async () => {163// Register a declared provider with an authorization server glob164const provider: AuthenticationProviderInformation = {165id: 'github',166label: 'GitHub',167authorizationServerGlobs: ['https://github.com/*']168};169authenticationService.registerDeclaredAuthenticationProvider(provider);170171// Register an authentication provider with non-matching authorization servers172const authProvider = createProvider({173id: 'github',174label: 'GitHub',175authorizationServers: [URI.parse('https://github.com/different')]176});177authenticationService.registerAuthenticationProvider('github', authProvider);178179// Test with a non-matching URI180const authorizationServer = URI.parse('https://github.com/login');181const result = await authenticationService.getOrActivateProviderIdForServer(authorizationServer);182183// Verify the result184assert.strictEqual(result, undefined);185});186187test('getOrActivateProviderIdForAuthorizationServer - should check multiple providers and return the first match', async () => {188// Register two declared providers with authorization server globs189const provider1: AuthenticationProviderInformation = {190id: 'github',191label: 'GitHub',192authorizationServerGlobs: ['https://github.com/*']193};194const provider2: AuthenticationProviderInformation = {195id: 'microsoft',196label: 'Microsoft',197authorizationServerGlobs: ['https://login.microsoftonline.com/*']198};199authenticationService.registerDeclaredAuthenticationProvider(provider1);200authenticationService.registerDeclaredAuthenticationProvider(provider2);201202// Register authentication providers203const githubProvider = createProvider({204id: 'github',205label: 'GitHub',206authorizationServers: [URI.parse('https://github.com/different')]207});208authenticationService.registerAuthenticationProvider('github', githubProvider);209210const microsoftProvider = createProvider({211id: 'microsoft',212label: 'Microsoft',213authorizationServers: [URI.parse('https://login.microsoftonline.com/common')]214});215authenticationService.registerAuthenticationProvider('microsoft', microsoftProvider);216217// Test with a URI that should match the second provider218const authorizationServer = URI.parse('https://login.microsoftonline.com/common');219const result = await authenticationService.getOrActivateProviderIdForServer(authorizationServer);220221// Verify the result222assert.strictEqual(result, 'microsoft');223});224});225226suite('authenticationSessions', () => {227test('getSessions - base case', async () => {228let isCalled = false;229const provider = createProvider({230getSessions: async () => {231isCalled = true;232return [createSession()];233},234});235authenticationService.registerAuthenticationProvider(provider.id, provider);236const sessions = await authenticationService.getSessions(provider.id);237238assert.equal(sessions.length, 1);239assert.ok(isCalled);240});241242test('getSessions - authorization server is not registered', async () => {243let isCalled = false;244const provider = createProvider({245getSessions: async () => {246isCalled = true;247return [createSession()];248},249});250authenticationService.registerAuthenticationProvider(provider.id, provider);251assert.rejects(() => authenticationService.getSessions(provider.id, [], { authorizationServer: URI.parse('https://example.com') }));252assert.ok(!isCalled);253});254255test('createSession', async () => {256const emitter = new Emitter<AuthenticationSessionsChangeEvent>();257const provider = createProvider({258onDidChangeSessions: emitter.event,259createSession: async () => {260const session = createSession();261emitter.fire({ added: [session], removed: [], changed: [] });262return session;263},264});265const changed = Event.toPromise(authenticationService.onDidChangeSessions);266authenticationService.registerAuthenticationProvider(provider.id, provider);267const session = await authenticationService.createSession(provider.id, ['repo']);268269// Assert that the created session matches the expected session and the event fires270assert.ok(session);271const result = await changed;272assert.deepEqual(result, {273providerId: provider.id,274label: provider.label,275event: { added: [session], removed: [], changed: [] }276});277});278279test('removeSession', async () => {280const emitter = new Emitter<AuthenticationSessionsChangeEvent>();281const session = createSession();282const provider = createProvider({283onDidChangeSessions: emitter.event,284removeSession: async () => emitter.fire({ added: [], removed: [session], changed: [] })285});286const changed = Event.toPromise(authenticationService.onDidChangeSessions);287authenticationService.registerAuthenticationProvider(provider.id, provider);288await authenticationService.removeSession(provider.id, session.id);289290const result = await changed;291assert.deepEqual(result, {292providerId: provider.id,293label: provider.label,294event: { added: [], removed: [session], changed: [] }295});296});297298test('onDidChangeSessions', async () => {299const emitter = new Emitter<AuthenticationSessionsChangeEvent>();300const provider = createProvider({301onDidChangeSessions: emitter.event,302getSessions: async () => []303});304authenticationService.registerAuthenticationProvider(provider.id, provider);305306const changed = Event.toPromise(authenticationService.onDidChangeSessions);307const session = createSession();308emitter.fire({ added: [], removed: [], changed: [session] });309310const result = await changed;311assert.deepEqual(result, {312providerId: provider.id,313label: provider.label,314event: { added: [], removed: [], changed: [session] }315});316});317});318});319320321