Path: blob/main/src/vs/platform/extensionManagement/test/common/allowedExtensionsService.test.ts
5251 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 * as assert from 'assert';6import { AllowedExtensionsService } from '../../common/allowedExtensionsService.js';7import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../base/test/common/utils.js';8import { IProductService } from '../../../product/common/productService.js';9import { TestConfigurationService } from '../../../configuration/test/common/testConfigurationService.js';10import { AllowedExtensionsConfigKey, IGalleryExtension, ILocalExtension } from '../../common/extensionManagement.js';11import { ExtensionType, IExtensionManifest, TargetPlatform } from '../../../extensions/common/extensions.js';12import { Event } from '../../../../base/common/event.js';13import { ConfigurationTarget } from '../../../configuration/common/configuration.js';14import { getGalleryExtensionId } from '../../common/extensionManagementUtil.js';15import { generateUuid } from '../../../../base/common/uuid.js';16import { URI } from '../../../../base/common/uri.js';17import { IStringDictionary } from '../../../../base/common/collections.js';1819suite('AllowedExtensionsService', () => {2021const disposables = ensureNoDisposablesAreLeakedInTestSuite();2223const configurationService = new TestConfigurationService();2425setup(() => {26configurationService.setUserConfiguration(AllowedExtensionsConfigKey, '*');27});2829test('should allow all extensions if no allowed extensions are configured', () => {30const testObject = disposables.add(new AllowedExtensionsService(aProductService(), configurationService));31assert.strictEqual(testObject.isAllowed({ id: 'test.extension', publisherDisplayName: undefined }) === true, true);32});3334test('should not allow specific extension if not in allowed list', () => {35configurationService.setUserConfiguration(AllowedExtensionsConfigKey, { 'test.extension': false });36const testObject = disposables.add(new AllowedExtensionsService(aProductService(), configurationService));37assert.strictEqual(testObject.isAllowed({ id: 'test.extension', publisherDisplayName: undefined }) === true, false);38});3940test('should allow specific extension if in allowed list', () => {41configurationService.setUserConfiguration(AllowedExtensionsConfigKey, { 'test.extension': true });42const testObject = disposables.add(new AllowedExtensionsService(aProductService(), configurationService));43assert.strictEqual(testObject.isAllowed({ id: 'test.extension', publisherDisplayName: undefined }) === true, true);44});4546test('should not allow pre-release extension if only stable is allowed', () => {47configurationService.setUserConfiguration(AllowedExtensionsConfigKey, { 'test.extension': 'stable' });48const testObject = disposables.add(new AllowedExtensionsService(aProductService(), configurationService));49assert.strictEqual(testObject.isAllowed({ id: 'test.extension', publisherDisplayName: undefined, prerelease: true }) === true, false);50});5152test('should allow pre-release extension if pre-release is allowed', () => {53configurationService.setUserConfiguration(AllowedExtensionsConfigKey, { 'test.extension': true });54const testObject = disposables.add(new AllowedExtensionsService(aProductService(), configurationService));55assert.strictEqual(testObject.isAllowed({ id: 'test.extension', publisherDisplayName: undefined, prerelease: true }) === true, true);56});5758test('should allow specific version of an extension when configured to that version', () => {59configurationService.setUserConfiguration(AllowedExtensionsConfigKey, { 'test.extension': ['1.2.3'] });60const testObject = disposables.add(new AllowedExtensionsService(aProductService(), configurationService));61assert.strictEqual(testObject.isAllowed({ id: 'test.extension', publisherDisplayName: undefined, version: '1.2.3' }) === true, true);62});6364test('should allow any version of an extension when a specific version is configured', () => {65configurationService.setUserConfiguration(AllowedExtensionsConfigKey, { 'test.extension': ['1.2.3'] });66const testObject = disposables.add(new AllowedExtensionsService(aProductService(), configurationService));67assert.strictEqual(testObject.isAllowed({ id: 'test.extension', publisherDisplayName: undefined }) === true, true);68});6970test('should allow any version of an extension when stable is configured', () => {71configurationService.setUserConfiguration(AllowedExtensionsConfigKey, { 'test.extension': 'stable' });72const testObject = disposables.add(new AllowedExtensionsService(aProductService(), configurationService));73assert.strictEqual(testObject.isAllowed({ id: 'test.extension', publisherDisplayName: undefined }) === true, true);74});7576test('should allow a version of an extension when stable is configured', () => {77configurationService.setUserConfiguration(AllowedExtensionsConfigKey, { 'test.extension': 'stable' });78const testObject = disposables.add(new AllowedExtensionsService(aProductService(), configurationService));79assert.strictEqual(testObject.isAllowed({ id: 'test.extension', publisherDisplayName: undefined, version: '1.2.3' }) === true, true);80});8182test('should allow a pre-release version of an extension when stable is configured', () => {83configurationService.setUserConfiguration(AllowedExtensionsConfigKey, { 'test.extension': 'stable' });84const testObject = disposables.add(new AllowedExtensionsService(aProductService(), configurationService));85assert.strictEqual(testObject.isAllowed({ id: 'test.extension', publisherDisplayName: undefined, version: '1.2.3', prerelease: true }) === true, false);86});8788test('should allow specific version of an extension when configured to multiple versions', () => {89configurationService.setUserConfiguration(AllowedExtensionsConfigKey, { 'test.extension': ['1.2.3', '2.0.1', '3.1.2'] });90const testObject = disposables.add(new AllowedExtensionsService(aProductService(), configurationService));91assert.strictEqual(testObject.isAllowed({ id: 'test.extension', publisherDisplayName: undefined, version: '1.2.3' }) === true, true);92});9394test('should allow platform specific version of an extension when configured to platform specific version', () => {95configurationService.setUserConfiguration(AllowedExtensionsConfigKey, { 'test.extension': ['1.2.3@darwin-x64'] });96const testObject = disposables.add(new AllowedExtensionsService(aProductService(), configurationService));97assert.strictEqual(testObject.isAllowed({ id: 'test.extension', publisherDisplayName: undefined, version: '1.2.3', targetPlatform: TargetPlatform.DARWIN_X64 }) === true, true);98});99100test('should allow universal platform specific version of an extension when configured to platform specific version', () => {101configurationService.setUserConfiguration(AllowedExtensionsConfigKey, { 'test.extension': ['1.2.3@darwin-x64'] });102const testObject = disposables.add(new AllowedExtensionsService(aProductService(), configurationService));103assert.strictEqual(testObject.isAllowed({ id: 'test.extension', publisherDisplayName: undefined, version: '1.2.3', targetPlatform: TargetPlatform.UNIVERSAL }) === true, true);104});105106test('should allow specific version of an extension when configured to platform specific version', () => {107configurationService.setUserConfiguration(AllowedExtensionsConfigKey, { 'test.extension': ['1.2.3@darwin-x64'] });108const testObject = disposables.add(new AllowedExtensionsService(aProductService(), configurationService));109assert.strictEqual(testObject.isAllowed({ id: 'test.extension', publisherDisplayName: undefined, version: '1.2.3' }) === true, true);110});111112test('should allow platform specific version of an extension when configured to multiple versions', () => {113configurationService.setUserConfiguration(AllowedExtensionsConfigKey, { 'test.extension': ['1.0.0', '1.2.3@darwin-x64', '1.2.3@darwin-arm64'] });114const testObject = disposables.add(new AllowedExtensionsService(aProductService(), configurationService));115assert.strictEqual(testObject.isAllowed({ id: 'test.extension', publisherDisplayName: undefined, version: '1.2.3', targetPlatform: TargetPlatform.DARWIN_X64 }) === true, true);116});117118test('should not allow platform specific version of an extension when configured to different platform specific version', () => {119configurationService.setUserConfiguration(AllowedExtensionsConfigKey, { 'test.extension': ['1.2.3@darwin-x64'] });120const testObject = disposables.add(new AllowedExtensionsService(aProductService(), configurationService));121assert.strictEqual(testObject.isAllowed({ id: 'test.extension', publisherDisplayName: undefined, version: '1.2.3', targetPlatform: TargetPlatform.DARWIN_ARM64 }) === true, false);122});123124test('should specific version of an extension when configured to different versions', () => {125configurationService.setUserConfiguration(AllowedExtensionsConfigKey, { 'test.extension': ['1.0.0', '1.2.3@darwin-x64', '1.2.3@darwin-arm64'] });126const testObject = disposables.add(new AllowedExtensionsService(aProductService(), configurationService));127assert.strictEqual(testObject.isAllowed({ id: 'test.extension', publisherDisplayName: undefined, version: '1.0.1' }) === true, false);128});129130test('should allow extension if publisher is in allowed list', () => {131configurationService.setUserConfiguration(AllowedExtensionsConfigKey, { 'test': true });132const testObject = disposables.add(new AllowedExtensionsService(aProductService(), configurationService));133assert.strictEqual(testObject.isAllowed({ id: 'test.extension', publisherDisplayName: undefined }), true);134});135136test('should allow extension if publisher is not in allowed list and has publisher mapping', () => {137configurationService.setUserConfiguration(AllowedExtensionsConfigKey, { 'hello': true });138const testObject = disposables.add(new AllowedExtensionsService(aProductService(['hello']), configurationService));139assert.strictEqual(testObject.isAllowed({ id: 'test.extension', publisherDisplayName: 'Hello' }), true);140});141142test('should allow extension if publisher is not in allowed list and has different publisher mapping', () => {143configurationService.setUserConfiguration(AllowedExtensionsConfigKey, { 'hello': true });144const testObject = disposables.add(new AllowedExtensionsService(aProductService(['bar']), configurationService));145assert.strictEqual(testObject.isAllowed({ id: 'test.extension', publisherDisplayName: 'Hello' }) === true, false);146});147148test('should not allow extension if publisher is not in allowed list', () => {149configurationService.setUserConfiguration(AllowedExtensionsConfigKey, { 'test': false });150const testObject = disposables.add(new AllowedExtensionsService(aProductService(), configurationService));151assert.strictEqual(testObject.isAllowed({ id: 'test.extension', publisherDisplayName: undefined }) === true, false);152});153154test('should not allow prerelease extension if publisher is allowed only to stable', () => {155configurationService.setUserConfiguration(AllowedExtensionsConfigKey, { 'test': 'stable' });156const testObject = disposables.add(new AllowedExtensionsService(aProductService(), configurationService));157assert.strictEqual(testObject.isAllowed({ id: 'test.extension', publisherDisplayName: undefined, prerelease: true }) === true, false);158});159160test('should allow extension if publisher is set to random value', () => {161configurationService.setUserConfiguration(AllowedExtensionsConfigKey, { 'test': 'hello' });162const testObject = disposables.add(new AllowedExtensionsService(aProductService(), configurationService));163assert.strictEqual(testObject.isAllowed({ id: 'test.extension', publisherDisplayName: undefined, prerelease: true }) === true, true);164});165166test('should allow extension if only wildcard is in allowed list', () => {167configurationService.setUserConfiguration(AllowedExtensionsConfigKey, { '*': true });168const testObject = disposables.add(new AllowedExtensionsService(aProductService(), configurationService));169assert.strictEqual(testObject.isAllowed({ id: 'test.extension', publisherDisplayName: undefined }), true);170});171172test('should allow extension if wildcard is in allowed list', () => {173configurationService.setUserConfiguration(AllowedExtensionsConfigKey, { '*': true, 'hello': false });174const testObject = disposables.add(new AllowedExtensionsService(aProductService(), configurationService));175assert.strictEqual(testObject.isAllowed({ id: 'test.extension', publisherDisplayName: undefined }), true);176});177178test('should not allow extension if wildcard is not in allowed list', () => {179configurationService.setUserConfiguration(AllowedExtensionsConfigKey, { '*': false, 'hello': true });180const testObject = disposables.add(new AllowedExtensionsService(aProductService(), configurationService));181assert.strictEqual(testObject.isAllowed({ id: 'test.extension', publisherDisplayName: undefined }) === true, false);182});183184test('should allow a gallery extension', () => {185configurationService.setUserConfiguration(AllowedExtensionsConfigKey, { 'pub': true });186const testObject = disposables.add(new AllowedExtensionsService(aProductService(), configurationService));187assert.strictEqual(testObject.isAllowed(aGalleryExtension('name')) === true, true);188});189190test('should allow a local extension', () => {191configurationService.setUserConfiguration(AllowedExtensionsConfigKey, { 'pub': true });192const testObject = disposables.add(new AllowedExtensionsService(aProductService(), configurationService));193assert.strictEqual(testObject.isAllowed(aLocalExtension('pub.name')) === true, true);194});195196test('should trigger change event when allowed list change', async () => {197configurationService.setUserConfiguration(AllowedExtensionsConfigKey, { '*': false });198const testObject = disposables.add(new AllowedExtensionsService(aProductService(), configurationService));199const promise = Event.toPromise(testObject.onDidChangeAllowedExtensionsConfigValue);200configurationService.onDidChangeConfigurationEmitter.fire({ affectsConfiguration: () => true, affectedKeys: new Set([AllowedExtensionsConfigKey]), change: { keys: [], overrides: [] }, source: ConfigurationTarget.USER });201await promise;202});203204function aProductService(extensionPublisherOrgs?: string[]): IProductService {205return {206_serviceBrand: undefined,207extensionPublisherOrgs208} as IProductService;209}210211function aGalleryExtension(name: string, properties: Partial<IGalleryExtension> = {}, galleryExtensionProperties: IStringDictionary<unknown> = {}): IGalleryExtension {212const galleryExtension = <IGalleryExtension>Object.create({ type: 'gallery', name, publisher: 'pub', publisherDisplayName: 'Pub', version: '1.0.0', allTargetPlatforms: [TargetPlatform.UNIVERSAL], properties: {}, assets: {}, isSigned: true, ...properties });213galleryExtension.properties = { ...galleryExtension.properties, dependencies: [], ...galleryExtensionProperties };214galleryExtension.identifier = { id: getGalleryExtensionId(galleryExtension.publisher, galleryExtension.name), uuid: generateUuid() };215return <IGalleryExtension>galleryExtension;216}217218function aLocalExtension(id: string, manifest: Partial<IExtensionManifest> = {}, properties: IStringDictionary<unknown> = {}): ILocalExtension {219const [publisher, name] = id.split('.');220manifest = { name, publisher, ...manifest };221properties = {222identifier: { id },223location: URI.file(`pub.${name}`),224galleryIdentifier: { id, uuid: undefined },225type: ExtensionType.User,226...properties,227isValid: properties.isValid ?? true,228};229properties.isBuiltin = properties.type === ExtensionType.System;230return <ILocalExtension>Object.create({ manifest, ...properties });231}232});233234235