Path: blob/main/src/vs/sessions/services/configuration/test/browser/configurationService.test.ts
13406 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 { URI } from '../../../../../base/common/uri.js';7import { Registry } from '../../../../../platform/registry/common/platform.js';8import { IConfigurationRegistry, Extensions as ConfigurationExtensions, ConfigurationScope } from '../../../../../platform/configuration/common/configurationRegistry.js';9import { ConfigurationTarget } from '../../../../../platform/configuration/common/configuration.js';10import { FileService } from '../../../../../platform/files/common/fileService.js';11import { NullLogService } from '../../../../../platform/log/common/log.js';12import { NullPolicyService } from '../../../../../platform/policy/common/policy.js';13import { VSBuffer } from '../../../../../base/common/buffer.js';14import { UriIdentityService } from '../../../../../platform/uriIdentity/common/uriIdentityService.js';15import { InMemoryFileSystemProvider } from '../../../../../platform/files/common/inMemoryFilesystemProvider.js';16import { joinPath } from '../../../../../base/common/resources.js';17import { Schemas } from '../../../../../base/common/network.js';18import { UserDataProfilesService } from '../../../../../platform/userDataProfile/common/userDataProfile.js';19import { UserDataProfileService } from '../../../../../workbench/services/userDataProfile/common/userDataProfileService.js';20import { FileUserDataProvider } from '../../../../../platform/userData/common/fileUserDataProvider.js';21import { TestEnvironmentService } from '../../../../../workbench/test/browser/workbenchTestServices.js';22import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../../base/test/common/utils.js';23import { runWithFakedTimers } from '../../../../../base/test/common/timeTravelScheduler.js';24import { ConfigurationService } from '../../browser/configurationService.js';25import { SessionsWorkspaceContextService } from '../../../workspace/browser/workspaceContextService.js';26import { getWorkspaceIdentifier } from '../../../../../workbench/services/workspaces/browser/workspaces.js';27import { Event } from '../../../../../base/common/event.js';28import { IUserDataProfileService } from '../../../../../workbench/services/userDataProfile/common/userDataProfile.js';2930const ROOT = URI.file('tests').with({ scheme: 'vscode-tests' });3132suite('Sessions ConfigurationService', () => {3334let testObject: ConfigurationService;35let workspaceService: SessionsWorkspaceContextService;36let fileService: FileService;37let userDataProfileService: IUserDataProfileService;38const configurationRegistry = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration);39const disposables = ensureNoDisposablesAreLeakedInTestSuite();4041suiteSetup(() => {42configurationRegistry.registerConfiguration({43'id': '_test_sessions',44'type': 'object',45'properties': {46'sessionsConfigurationService.testSetting': {47'type': 'string',48'default': 'defaultValue',49scope: ConfigurationScope.RESOURCE50},51'sessionsConfigurationService.machineSetting': {52'type': 'string',53'default': 'defaultValue',54scope: ConfigurationScope.MACHINE55},56'sessionsConfigurationService.applicationSetting': {57'type': 'string',58'default': 'defaultValue',59scope: ConfigurationScope.APPLICATION60},61}62});63});6465setup(async () => {66const logService = new NullLogService();67fileService = disposables.add(new FileService(logService));68const fileSystemProvider = disposables.add(new InMemoryFileSystemProvider());69disposables.add(fileService.registerProvider(ROOT.scheme, fileSystemProvider));7071const environmentService = TestEnvironmentService;72const uriIdentityService = disposables.add(new UriIdentityService(fileService));73const userDataProfilesService = disposables.add(new UserDataProfilesService(environmentService, fileService, uriIdentityService, logService));74disposables.add(fileService.registerProvider(Schemas.vscodeUserData, disposables.add(new FileUserDataProvider(ROOT.scheme, fileSystemProvider, Schemas.vscodeUserData, userDataProfilesService, uriIdentityService, logService))));75userDataProfileService = disposables.add(new UserDataProfileService(userDataProfilesService.defaultProfile));7677const configResource = joinPath(ROOT, 'agent-sessions.code-workspace');78await fileService.writeFile(configResource, VSBuffer.fromString(JSON.stringify({ folders: [] })));7980workspaceService = disposables.add(new SessionsWorkspaceContextService(getWorkspaceIdentifier(configResource), uriIdentityService));81testObject = disposables.add(new ConfigurationService(userDataProfileService, workspaceService, uriIdentityService, fileService, new NullPolicyService(), logService));82await testObject.initialize();83});8485// #region Reading8687test('defaults', () => {88assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting'), 'defaultValue');89assert.strictEqual(testObject.getValue('sessionsConfigurationService.machineSetting'), 'defaultValue');90assert.strictEqual(testObject.getValue('sessionsConfigurationService.applicationSetting'), 'defaultValue');91});9293test('user settings override defaults', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {94await fileService.writeFile(userDataProfileService.currentProfile.settingsResource, VSBuffer.fromString('{ "sessionsConfigurationService.testSetting": "userValue" }'));95await testObject.reloadConfiguration();96assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting'), 'userValue');97}));9899test('workspace folder settings override user settings', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {100const folder = joinPath(ROOT, 'myFolder');101await fileService.createFolder(folder);102await fileService.writeFile(userDataProfileService.currentProfile.settingsResource, VSBuffer.fromString('{ "sessionsConfigurationService.testSetting": "userValue" }'));103await testObject.reloadConfiguration();104await fileService.writeFile(joinPath(folder, '.vscode', 'settings.json'), VSBuffer.fromString('{ "sessionsConfigurationService.testSetting": "folderValue" }'));105await workspaceService.addFolders([{ uri: folder }]);106assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting', { resource: folder }), 'folderValue');107}));108109test('folder settings are read when folders are added', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {110const folder = joinPath(ROOT, 'addedFolder');111await fileService.createFolder(folder);112await fileService.writeFile(joinPath(folder, '.vscode', 'settings.json'), VSBuffer.fromString('{ "sessionsConfigurationService.testSetting": "folderValue" }'));113await workspaceService.addFolders([{ uri: folder }]);114assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting', { resource: folder }), 'folderValue');115}));116117test('folder settings are removed when folders are removed', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {118const folder = joinPath(ROOT, 'removedFolder');119await fileService.createFolder(folder);120await fileService.writeFile(joinPath(folder, '.vscode', 'settings.json'), VSBuffer.fromString('{ "sessionsConfigurationService.testSetting": "folderValue" }'));121await workspaceService.addFolders([{ uri: folder }]);122assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting', { resource: folder }), 'folderValue');123await workspaceService.removeFolders([folder]);124assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting', { resource: folder }), 'defaultValue');125}));126127test('configuration change event is fired when folders with settings are removed', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {128const folder = joinPath(ROOT, 'removedFolder2');129await fileService.createFolder(folder);130await fileService.writeFile(joinPath(folder, '.vscode', 'settings.json'), VSBuffer.fromString('{ "sessionsConfigurationService.testSetting": "folderValue" }'));131await workspaceService.addFolders([{ uri: folder }]);132assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting', { resource: folder }), 'folderValue');133134const promise = Event.toPromise(testObject.onDidChangeConfiguration);135await workspaceService.removeFolders([folder]);136const event = await promise;137assert.ok(event.affectsConfiguration('sessionsConfigurationService.testSetting'));138assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting', { resource: folder }), 'defaultValue');139}));140141test('configuration change event is fired on user settings change', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {142const promise = Event.toPromise(testObject.onDidChangeConfiguration);143await fileService.writeFile(userDataProfileService.currentProfile.settingsResource, VSBuffer.fromString('{ "sessionsConfigurationService.testSetting": "userValue" }'));144await testObject.reloadConfiguration();145const event = await promise;146assert.ok(event.affectsConfiguration('sessionsConfigurationService.testSetting'));147}));148149test('inspect returns correct values per layer', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {150const folder = joinPath(ROOT, 'inspectFolder');151await fileService.createFolder(folder);152await fileService.writeFile(userDataProfileService.currentProfile.settingsResource, VSBuffer.fromString('{ "sessionsConfigurationService.testSetting": "userValue" }'));153await testObject.reloadConfiguration();154await fileService.writeFile(joinPath(folder, '.vscode', 'settings.json'), VSBuffer.fromString('{ "sessionsConfigurationService.testSetting": "folderValue" }'));155await workspaceService.addFolders([{ uri: folder }]);156157const inspection = testObject.inspect('sessionsConfigurationService.testSetting', { resource: folder });158assert.strictEqual(inspection.defaultValue, 'defaultValue');159assert.strictEqual(inspection.userValue, 'userValue');160assert.strictEqual(inspection.workspaceFolderValue, 'folderValue');161}));162163test('application settings are not read from workspace folder', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {164const folder = joinPath(ROOT, 'appFolder');165await fileService.createFolder(folder);166await fileService.writeFile(joinPath(folder, '.vscode', 'settings.json'), VSBuffer.fromString('{ "sessionsConfigurationService.applicationSetting": "folderValue" }'));167await workspaceService.addFolders([{ uri: folder }]);168assert.strictEqual(testObject.getValue('sessionsConfigurationService.applicationSetting', { resource: folder }), 'defaultValue');169}));170171test('machine settings are not read from workspace folder', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {172const folder = joinPath(ROOT, 'machineFolder');173await fileService.createFolder(folder);174await fileService.writeFile(joinPath(folder, '.vscode', 'settings.json'), VSBuffer.fromString('{ "sessionsConfigurationService.machineSetting": "folderValue" }'));175await workspaceService.addFolders([{ uri: folder }]);176assert.strictEqual(testObject.getValue('sessionsConfigurationService.machineSetting', { resource: folder }), 'defaultValue');177}));178179test('folder settings change fires configuration change event', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {180const folder = joinPath(ROOT, 'changeFolder');181await fileService.createFolder(folder);182await fileService.writeFile(joinPath(folder, '.vscode', 'settings.json'), VSBuffer.fromString('{ "sessionsConfigurationService.testSetting": "initialValue" }'));183await workspaceService.addFolders([{ uri: folder }]);184assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting', { resource: folder }), 'initialValue');185186const promise = Event.toPromise(testObject.onDidChangeConfiguration);187await fileService.writeFile(joinPath(folder, '.vscode', 'settings.json'), VSBuffer.fromString('{ "sessionsConfigurationService.testSetting": "updatedValue" }'));188const event = await promise;189assert.ok(event.affectsConfiguration('sessionsConfigurationService.testSetting'));190assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting', { resource: folder }), 'updatedValue');191}));192193// #endregion194195// #region Writing196197test('updateValue writes to user settings', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {198await testObject.updateValue('sessionsConfigurationService.testSetting', 'writtenValue');199assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting'), 'writtenValue');200}));201202test('updateValue persists to settings file', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {203await testObject.updateValue('sessionsConfigurationService.testSetting', 'persistedValue');204205const content = (await fileService.readFile(userDataProfileService.currentProfile.settingsResource)).value.toString();206assert.ok(content.includes('"sessionsConfigurationService.testSetting"'));207assert.ok(content.includes('persistedValue'));208}));209210test('updateValue fires change event', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {211const promise = Event.toPromise(testObject.onDidChangeConfiguration);212await testObject.updateValue('sessionsConfigurationService.testSetting', 'eventValue');213const event = await promise;214assert.ok(event.affectsConfiguration('sessionsConfigurationService.testSetting'));215}));216217test('updateValue removes setting when value equals default', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {218await testObject.updateValue('sessionsConfigurationService.testSetting', 'nonDefault');219assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting'), 'nonDefault');220221await testObject.updateValue('sessionsConfigurationService.testSetting', 'defaultValue');222const content = (await fileService.readFile(userDataProfileService.currentProfile.settingsResource)).value.toString();223assert.ok(!content.includes('sessionsConfigurationService.testSetting'));224}));225226test('updateValue can update multiple settings', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {227await testObject.updateValue('sessionsConfigurationService.testSetting', 'value1');228await testObject.updateValue('sessionsConfigurationService.machineSetting', 'value2');229assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting'), 'value1');230assert.strictEqual(testObject.getValue('sessionsConfigurationService.machineSetting'), 'value2');231}));232233test('updateValue with language override', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {234await testObject.updateValue('sessionsConfigurationService.testSetting', 'langValue', { overrideIdentifier: 'jsonc' });235assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting', { overrideIdentifier: 'jsonc' }), 'langValue');236assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting'), 'defaultValue');237}));238239test('updateValue is reflected in inspect', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {240await testObject.updateValue('sessionsConfigurationService.testSetting', 'inspectedValue');241const inspection = testObject.inspect('sessionsConfigurationService.testSetting');242assert.strictEqual(inspection.defaultValue, 'defaultValue');243assert.strictEqual(inspection.userValue, 'inspectedValue');244}));245246// #endregion247248// #region Workspace Folder - Read and Write249250test('read setting from workspace folder', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {251const folder = joinPath(ROOT, 'readFolder');252await fileService.createFolder(folder);253await fileService.writeFile(joinPath(folder, '.vscode', 'settings.json'), VSBuffer.fromString('{ "sessionsConfigurationService.testSetting": "folderValue" }'));254255await workspaceService.addFolders([{ uri: folder }]);256257assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting', { resource: folder }), 'folderValue');258assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting'), 'defaultValue');259}));260261test('write setting to workspace folder', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {262const folder = joinPath(ROOT, 'writeFolder');263await fileService.createFolder(folder);264265await workspaceService.addFolders([{ uri: folder }]);266267await testObject.updateValue('sessionsConfigurationService.testSetting', 'writtenFolderValue', { resource: folder }, ConfigurationTarget.WORKSPACE_FOLDER);268269assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting', { resource: folder }), 'writtenFolderValue');270}));271272test('write setting to workspace folder persists to folder settings file', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {273const folder = joinPath(ROOT, 'persistFolder');274await fileService.createFolder(folder);275276await workspaceService.addFolders([{ uri: folder }]);277278await testObject.updateValue('sessionsConfigurationService.testSetting', 'persistedFolderValue', { resource: folder }, ConfigurationTarget.WORKSPACE_FOLDER);279280const content = (await fileService.readFile(joinPath(folder, '.vscode', 'settings.json'))).value.toString();281assert.ok(content.includes('"sessionsConfigurationService.testSetting"'));282assert.ok(content.includes('persistedFolderValue'));283}));284285test('write setting to workspace folder does not affect user settings', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {286const folder = joinPath(ROOT, 'isolateFolder');287await fileService.createFolder(folder);288289await workspaceService.addFolders([{ uri: folder }]);290291await testObject.updateValue('sessionsConfigurationService.testSetting', 'folderOnly', { resource: folder }, ConfigurationTarget.WORKSPACE_FOLDER);292293assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting', { resource: folder }), 'folderOnly');294assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting'), 'defaultValue');295}));296297test('workspace folder setting overrides user setting for resource', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {298const folder = joinPath(ROOT, 'overrideFolder');299await fileService.createFolder(folder);300301await workspaceService.addFolders([{ uri: folder }]);302303await testObject.updateValue('sessionsConfigurationService.testSetting', 'userValue');304await testObject.updateValue('sessionsConfigurationService.testSetting', 'folderValue', { resource: folder }, ConfigurationTarget.WORKSPACE_FOLDER);305306assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting', { resource: folder }), 'folderValue');307assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting'), 'userValue');308}));309310test('inspect shows workspace folder value after write', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {311const folder = joinPath(ROOT, 'inspectWriteFolder');312await fileService.createFolder(folder);313314await workspaceService.addFolders([{ uri: folder }]);315316await testObject.updateValue('sessionsConfigurationService.testSetting', 'userVal');317await testObject.updateValue('sessionsConfigurationService.testSetting', 'folderVal', { resource: folder }, ConfigurationTarget.WORKSPACE_FOLDER);318319const inspection = testObject.inspect('sessionsConfigurationService.testSetting', { resource: folder });320assert.strictEqual(inspection.defaultValue, 'defaultValue');321assert.strictEqual(inspection.userValue, 'userVal');322assert.strictEqual(inspection.workspaceFolderValue, 'folderVal');323}));324325test('removing folder clears its written settings', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {326const folder = joinPath(ROOT, 'clearFolder');327await fileService.createFolder(folder);328329await workspaceService.addFolders([{ uri: folder }]);330await testObject.updateValue('sessionsConfigurationService.testSetting', 'folderValue', { resource: folder }, ConfigurationTarget.WORKSPACE_FOLDER);331assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting', { resource: folder }), 'folderValue');332333await workspaceService.removeFolders([folder]);334assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting', { resource: folder }), 'defaultValue');335}));336337// #endregion338});339340341