extensionsViews.test.ts 28.8 KB
Newer Older
R
Ramya Achutha Rao 已提交
1 2 3 4 5 6 7
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

import * as assert from 'assert';
import { generateUuid } from 'vs/base/common/uuid';
8
import { ExtensionsListView } from 'vs/workbench/contrib/extensions/browser/extensionsViews';
R
Ramya Achutha Rao 已提交
9
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
10
import { IExtensionsWorkbenchService } from 'vs/workbench/contrib/extensions/common/extensions';
11
import { ExtensionsWorkbenchService } from 'vs/workbench/contrib/extensions/browser/extensionsWorkbenchService';
R
Ramya Achutha Rao 已提交
12
import {
13 14
	IExtensionManagementService, IExtensionGalleryService, ILocalExtension, IGalleryExtension, IQueryOptions,
	DidInstallExtensionEvent, DidUninstallExtensionEvent, InstallExtensionEvent, IExtensionIdentifier, SortBy
R
Ramya Achutha Rao 已提交
15
} from 'vs/platform/extensionManagement/common/extensionManagement';
S
Sandeep Somavarapu 已提交
16
import { IWorkbenchExtensionEnablementService, EnablementState, IExtensionManagementServerService, IExtensionManagementServer, IExtensionRecommendationsService, ExtensionRecommendationReason, IExtensionRecommendation } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
17
import { getGalleryExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
18
import { TestExtensionEnablementService } from 'vs/workbench/services/extensionManagement/test/browser/extensionEnablementService.test';
19
import { ExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionGalleryService';
R
Ramya Achutha Rao 已提交
20 21 22 23 24 25 26
import { IURLService } from 'vs/platform/url/common/url';
import { Emitter } from 'vs/base/common/event';
import { IPager } from 'vs/base/common/paging';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils';
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
27
import { TestMenuService } from 'vs/workbench/test/browser/workbenchTestServices';
28
import { TestSharedProcessService } from 'vs/workbench/test/electron-browser/workbenchTestServices';
R
Ramya Achutha Rao 已提交
29 30
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { ILogService, NullLogService } from 'vs/platform/log/common/log';
B
Benjamin Pasero 已提交
31
import { NativeURLService } from 'vs/platform/url/common/urlService';
R
Ramya Achutha Rao 已提交
32 33 34
import { URI } from 'vs/base/common/uri';
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
import { SinonStub } from 'sinon';
S
Sandeep Somavarapu 已提交
35
import { IExperimentService, ExperimentState, ExperimentActionType, ExperimentService } from 'vs/workbench/contrib/experiments/common/experimentService';
36
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
37
import { RemoteAgentService } from 'vs/workbench/services/remote/electron-browser/remoteAgentServiceImpl';
38
import { ExtensionIdentifier, ExtensionType, IExtensionDescription } from 'vs/platform/extensions/common/extensions';
39
import { ISharedProcessService } from 'vs/platform/ipc/electron-browser/sharedProcessService';
40
import { ExtensionManagementServerService } from 'vs/workbench/services/extensionManagement/electron-browser/extensionManagementServerService';
41
import { ILabelService } from 'vs/platform/label/common/label';
S
Sandeep Somavarapu 已提交
42 43
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { MockContextKeyService } from 'vs/platform/keybinding/test/common/mockKeybindingService';
44
import { IMenuService } from 'vs/platform/actions/common/actions';
45
import { TestContextService } from 'vs/workbench/test/common/workbenchTestServices';
S
SteVen Batten 已提交
46
import { IViewDescriptorService, ViewContainerLocation } from 'vs/workbench/common/views';
R
Ramya Achutha Rao 已提交
47 48 49 50 51 52 53 54 55 56

suite('ExtensionsListView Tests', () => {

	let instantiationService: TestInstantiationService;
	let testableView: ExtensionsListView;
	let installEvent: Emitter<InstallExtensionEvent>,
		didInstallEvent: Emitter<DidInstallExtensionEvent>,
		uninstallEvent: Emitter<IExtensionIdentifier>,
		didUninstallEvent: Emitter<DidUninstallExtensionEvent>;

57 58 59 60 61
	const localEnabledTheme = aLocalExtension('first-enabled-extension', { categories: ['Themes', 'random'] });
	const localEnabledLanguage = aLocalExtension('second-enabled-extension', { categories: ['Programming languages'] });
	const localDisabledTheme = aLocalExtension('first-disabled-extension', { categories: ['themes'] });
	const localDisabledLanguage = aLocalExtension('second-disabled-extension', { categories: ['programming languages'] });
	const localRandom = aLocalExtension('random-enabled-extension', { categories: ['random'] });
62 63
	const builtInTheme = aLocalExtension('my-theme', { contributes: { themes: ['my-theme'] } }, { type: ExtensionType.System });
	const builtInBasic = aLocalExtension('my-lang', { contributes: { grammars: [{ language: 'my-language' }] } }, { type: ExtensionType.System });
R
Ramya Achutha Rao 已提交
64 65 66

	const workspaceRecommendationA = aGalleryExtension('workspace-recommendation-A');
	const workspaceRecommendationB = aGalleryExtension('workspace-recommendation-B');
67
	const configBasedRecommendationA = aGalleryExtension('configbased-recommendation-A');
68
	const configBasedRecommendationB = aGalleryExtension('configbased-recommendation-B');
R
Ramya Achutha Rao 已提交
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
	const fileBasedRecommendationA = aGalleryExtension('filebased-recommendation-A');
	const fileBasedRecommendationB = aGalleryExtension('filebased-recommendation-B');
	const otherRecommendationA = aGalleryExtension('other-recommendation-A');

	suiteSetup(() => {
		installEvent = new Emitter<InstallExtensionEvent>();
		didInstallEvent = new Emitter<DidInstallExtensionEvent>();
		uninstallEvent = new Emitter<IExtensionIdentifier>();
		didUninstallEvent = new Emitter<DidUninstallExtensionEvent>();

		instantiationService = new TestInstantiationService();
		instantiationService.stub(ITelemetryService, NullTelemetryService);
		instantiationService.stub(ILogService, NullLogService);

		instantiationService.stub(IWorkspaceContextService, new TestContextService());
		instantiationService.stub(IConfigurationService, new TestConfigurationService());

		instantiationService.stub(IExtensionGalleryService, ExtensionGalleryService);
87
		instantiationService.stub(ISharedProcessService, TestSharedProcessService);
R
Ramya Achutha Rao 已提交
88 89
		instantiationService.stub(IExperimentService, ExperimentService);

90 91 92 93 94 95 96 97 98
		instantiationService.stub(IExtensionManagementService, <Partial<IExtensionManagementService>>{
			onInstallExtension: installEvent.event,
			onDidInstallExtension: didInstallEvent.event,
			onUninstallExtension: uninstallEvent.event,
			onDidUninstallExtension: didUninstallEvent.event,
			async getInstalled() { return []; },
			async canInstall() { return true; },
			async getExtensionsReport() { return []; },
		});
99
		instantiationService.stub(IRemoteAgentService, RemoteAgentService);
100 101
		instantiationService.stub(IContextKeyService, new MockContextKeyService());
		instantiationService.stub(IMenuService, new TestMenuService());
R
Ramya Achutha Rao 已提交
102

S
Sandeep Somavarapu 已提交
103
		instantiationService.stub(IExtensionManagementServerService, new class extends ExtensionManagementServerService {
104
			#localExtensionManagementServer: IExtensionManagementServer = { extensionManagementService: instantiationService.get(IExtensionManagementService), label: 'local', id: 'vscode-local' };
S
Sandeep Somavarapu 已提交
105
			constructor() {
106
				super(instantiationService.get(ISharedProcessService), instantiationService.get(IRemoteAgentService), instantiationService.get(ILabelService), instantiationService.get(IExtensionGalleryService), instantiationService);
107
			}
108
			get localExtensionManagementServer(): IExtensionManagementServer { return this.#localExtensionManagementServer; }
S
Sandeep Somavarapu 已提交
109 110
			set localExtensionManagementServer(server: IExtensionManagementServer) { }
		}());
R
Ramya Achutha Rao 已提交
111

S
rename  
Sandeep Somavarapu 已提交
112
		instantiationService.stub(IWorkbenchExtensionEnablementService, new TestExtensionEnablementService(instantiationService));
R
Ramya Achutha Rao 已提交
113

114
		const reasons: { [key: string]: any } = {};
R
Ramya Achutha Rao 已提交
115 116 117 118 119
		reasons[workspaceRecommendationA.identifier.id] = { reasonId: ExtensionRecommendationReason.Workspace };
		reasons[workspaceRecommendationB.identifier.id] = { reasonId: ExtensionRecommendationReason.Workspace };
		reasons[fileBasedRecommendationA.identifier.id] = { reasonId: ExtensionRecommendationReason.File };
		reasons[fileBasedRecommendationB.identifier.id] = { reasonId: ExtensionRecommendationReason.File };
		reasons[otherRecommendationA.identifier.id] = { reasonId: ExtensionRecommendationReason.Executable };
120
		reasons[configBasedRecommendationA.identifier.id] = { reasonId: ExtensionRecommendationReason.WorkspaceConfig };
S
Sandeep Somavarapu 已提交
121 122 123 124 125 126
		instantiationService.stub(IExtensionRecommendationsService, <Partial<IExtensionRecommendationsService>>{
			getWorkspaceRecommendations() {
				return Promise.resolve([
					{ extensionId: workspaceRecommendationA.identifier.id },
					{ extensionId: workspaceRecommendationB.identifier.id }]);
			},
127
			getConfigBasedRecommendations() {
128 129 130 131
				return Promise.resolve({
					important: [{ extensionId: configBasedRecommendationA.identifier.id }],
					others: [{ extensionId: configBasedRecommendationB.identifier.id }],
				});
132
			},
S
Sandeep Somavarapu 已提交
133 134 135
			getImportantRecommendations(): Promise<IExtensionRecommendation[]> {
				return Promise.resolve([]);
			},
S
Sandeep Somavarapu 已提交
136 137 138 139 140 141 142 143
			getFileBasedRecommendations() {
				return [
					{ extensionId: fileBasedRecommendationA.identifier.id },
					{ extensionId: fileBasedRecommendationB.identifier.id }
				];
			},
			getOtherRecommendations() {
				return Promise.resolve([
144
					{ extensionId: configBasedRecommendationB.identifier.id },
S
Sandeep Somavarapu 已提交
145 146 147 148 149 150 151
					{ extensionId: otherRecommendationA.identifier.id }
				]);
			},
			getAllRecommendationsWithReason() {
				return reasons;
			}
		});
B
Benjamin Pasero 已提交
152
		instantiationService.stub(IURLService, NativeURLService);
R
Ramya Achutha Rao 已提交
153 154 155
	});

	setup(async () => {
156
		instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [localEnabledTheme, localEnabledLanguage, localRandom, localDisabledTheme, localDisabledLanguage, builtInTheme, builtInBasic]);
R
Ramya Achutha Rao 已提交
157 158
		instantiationService.stubPromise(IExtensionManagementService, 'getExtensionsReport', []);
		instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage());
R
Ramya Achutha Rao 已提交
159
		instantiationService.stubPromise(IExperimentService, 'getExperimentsByType', []);
R
Ramya Achutha Rao 已提交
160

S
SteVen Batten 已提交
161
		instantiationService.stub(IViewDescriptorService, {
162
			getViewLocationById(): ViewContainerLocation {
S
SteVen Batten 已提交
163 164 165 166
				return ViewContainerLocation.Sidebar;
			}
		});

R
Ramya Achutha Rao 已提交
167
		instantiationService.stub(IExtensionService, {
168
			getExtensions: (): Promise<IExtensionDescription[]> => {
169
				return Promise.resolve([
170 171 172 173 174
					toExtensionDescription(localEnabledTheme),
					toExtensionDescription(localEnabledLanguage),
					toExtensionDescription(localRandom),
					toExtensionDescription(builtInTheme),
					toExtensionDescription(builtInBasic)
175
				]);
R
Ramya Achutha Rao 已提交
176 177
			}
		});
S
rename  
Sandeep Somavarapu 已提交
178 179
		await (<TestExtensionEnablementService>instantiationService.get(IWorkbenchExtensionEnablementService)).setEnablement([localDisabledTheme], EnablementState.DisabledGlobally);
		await (<TestExtensionEnablementService>instantiationService.get(IWorkbenchExtensionEnablementService)).setEnablement([localDisabledLanguage], EnablementState.DisabledGlobally);
R
Ramya Achutha Rao 已提交
180 181 182 183 184 185 186 187 188 189 190 191

		instantiationService.set(IExtensionsWorkbenchService, instantiationService.createInstance(ExtensionsWorkbenchService));
		testableView = instantiationService.createInstance(ExtensionsListView, {});
	});

	teardown(() => {
		(<ExtensionsWorkbenchService>instantiationService.get(IExtensionsWorkbenchService)).dispose();
		testableView.dispose();
	});

	test('Test query types', () => {
		assert.equal(ExtensionsListView.isBuiltInExtensionsQuery('@builtin'), true);
192 193 194 195 196 197 198 199
		assert.equal(ExtensionsListView.isLocalExtensionsQuery('@installed'), true);
		assert.equal(ExtensionsListView.isLocalExtensionsQuery('@enabled'), true);
		assert.equal(ExtensionsListView.isLocalExtensionsQuery('@disabled'), true);
		assert.equal(ExtensionsListView.isLocalExtensionsQuery('@outdated'), true);
		assert.equal(ExtensionsListView.isLocalExtensionsQuery('@installed searchText'), true);
		assert.equal(ExtensionsListView.isLocalExtensionsQuery('@enabled searchText'), true);
		assert.equal(ExtensionsListView.isLocalExtensionsQuery('@disabled searchText'), true);
		assert.equal(ExtensionsListView.isLocalExtensionsQuery('@outdated searchText'), true);
R
Ramya Achutha Rao 已提交
200 201
	});

202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228
	test('Test empty query equates to sort by install count', () => {
		const target = <SinonStub>instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage());
		return testableView.show('').then(() => {
			assert.ok(target.calledOnce);
			const options: IQueryOptions = target.args[0][0];
			assert.equal(options.sortBy, SortBy.InstallCount);
		});
	});

	test('Test non empty query without sort doesnt use sortBy', () => {
		const target = <SinonStub>instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage());
		return testableView.show('some extension').then(() => {
			assert.ok(target.calledOnce);
			const options: IQueryOptions = target.args[0][0];
			assert.equal(options.sortBy, undefined);
		});
	});

	test('Test query with sort uses sortBy', () => {
		const target = <SinonStub>instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage());
		return testableView.show('some extension @sort:rating').then(() => {
			assert.ok(target.calledOnce);
			const options: IQueryOptions = target.args[0][0];
			assert.equal(options.sortBy, SortBy.WeightedRating);
		});
	});

S
Sandeep Somavarapu 已提交
229 230
	test('Test installed query results', async () => {
		await testableView.show('@installed').then(result => {
231 232 233 234 235 236
			assert.equal(result.length, 5, 'Unexpected number of results for @installed query');
			const actual = [result.get(0).name, result.get(1).name, result.get(2).name, result.get(3).name, result.get(4).name].sort();
			const expected = [localDisabledTheme.manifest.name, localEnabledTheme.manifest.name, localRandom.manifest.name, localDisabledLanguage.manifest.name, localEnabledLanguage.manifest.name];
			for (let i = 0; i < result.length; i++) {
				assert.equal(actual[i], expected[i], 'Unexpected extension for @installed query.');
			}
R
Ramya Achutha Rao 已提交
237 238
		});

S
Sandeep Somavarapu 已提交
239
		await testableView.show('@installed first').then(result => {
240
			assert.equal(result.length, 2, 'Unexpected number of results for @installed query');
S
Sandeep Somavarapu 已提交
241 242
			assert.equal(result.get(0).name, localEnabledTheme.manifest.name, 'Unexpected extension for @installed query with search text.');
			assert.equal(result.get(1).name, localDisabledTheme.manifest.name, 'Unexpected extension for @installed query with search text.');
R
Ramya Achutha Rao 已提交
243 244
		});

S
Sandeep Somavarapu 已提交
245
		await testableView.show('@disabled').then(result => {
246 247 248
			assert.equal(result.length, 2, 'Unexpected number of results for @disabled query');
			assert.equal(result.get(0).name, localDisabledTheme.manifest.name, 'Unexpected extension for @disabled query.');
			assert.equal(result.get(1).name, localDisabledLanguage.manifest.name, 'Unexpected extension for @disabled query.');
R
Ramya Achutha Rao 已提交
249 250
		});

S
Sandeep Somavarapu 已提交
251
		await testableView.show('@enabled').then(result => {
252 253 254 255
			assert.equal(result.length, 3, 'Unexpected number of results for @enabled query');
			assert.equal(result.get(0).name, localEnabledTheme.manifest.name, 'Unexpected extension for @enabled query.');
			assert.equal(result.get(1).name, localRandom.manifest.name, 'Unexpected extension for @enabled query.');
			assert.equal(result.get(2).name, localEnabledLanguage.manifest.name, 'Unexpected extension for @enabled query.');
R
Ramya Achutha Rao 已提交
256 257
		});

S
Sandeep Somavarapu 已提交
258
		await testableView.show('@builtin:themes').then(result => {
R
Ramya Achutha Rao 已提交
259 260 261 262
			assert.equal(result.length, 1, 'Unexpected number of results for @builtin:themes query');
			assert.equal(result.get(0).name, builtInTheme.manifest.name, 'Unexpected extension for @builtin:themes query.');
		});

S
Sandeep Somavarapu 已提交
263
		await testableView.show('@builtin:basics').then(result => {
R
Ramya Achutha Rao 已提交
264 265 266 267
			assert.equal(result.length, 1, 'Unexpected number of results for @builtin:basics query');
			assert.equal(result.get(0).name, builtInBasic.manifest.name, 'Unexpected extension for @builtin:basics query.');
		});

S
Sandeep Somavarapu 已提交
268
		await testableView.show('@builtin').then(result => {
R
Ramya Achutha Rao 已提交
269 270 271 272 273
			assert.equal(result.length, 2, 'Unexpected number of results for @builtin query');
			assert.equal(result.get(0).name, builtInBasic.manifest.name, 'Unexpected extension for @builtin query.');
			assert.equal(result.get(1).name, builtInTheme.manifest.name, 'Unexpected extension for @builtin query.');
		});

S
Sandeep Somavarapu 已提交
274
		await testableView.show('@builtin my-theme').then(result => {
R
Ramya Achutha Rao 已提交
275 276 277
			assert.equal(result.length, 1, 'Unexpected number of results for @builtin query');
			assert.equal(result.get(0).name, builtInTheme.manifest.name, 'Unexpected extension for @builtin query.');
		});
278 279
	});

S
Sandeep Somavarapu 已提交
280 281
	test('Test installed query with category', async () => {
		await testableView.show('@installed category:themes').then(result => {
282
			assert.equal(result.length, 2, 'Unexpected number of results for @installed query with category');
S
Sandeep Somavarapu 已提交
283 284
			assert.equal(result.get(0).name, localEnabledTheme.manifest.name, 'Unexpected extension for @installed query with category.');
			assert.equal(result.get(1).name, localDisabledTheme.manifest.name, 'Unexpected extension for @installed query with category.');
285 286
		});

S
Sandeep Somavarapu 已提交
287
		await testableView.show('@installed category:"themes"').then(result => {
288
			assert.equal(result.length, 2, 'Unexpected number of results for @installed query with quoted category');
S
Sandeep Somavarapu 已提交
289 290
			assert.equal(result.get(0).name, localEnabledTheme.manifest.name, 'Unexpected extension for @installed query with quoted category.');
			assert.equal(result.get(1).name, localDisabledTheme.manifest.name, 'Unexpected extension for @installed query with quoted category.');
291 292
		});

S
Sandeep Somavarapu 已提交
293
		await testableView.show('@installed category:"programming languages"').then(result => {
294
			assert.equal(result.length, 2, 'Unexpected number of results for @installed query with quoted category including space');
S
Sandeep Somavarapu 已提交
295 296
			assert.equal(result.get(0).name, localEnabledLanguage.manifest.name, 'Unexpected extension for @installed query with quoted category including space.');
			assert.equal(result.get(1).name, localDisabledLanguage.manifest.name, 'Unexpected extension for @installed query with quoted category inlcuding space.');
297 298
		});

S
Sandeep Somavarapu 已提交
299
		await testableView.show('@installed category:themes category:random').then(result => {
300
			assert.equal(result.length, 3, 'Unexpected number of results for @installed query with multiple category');
S
Sandeep Somavarapu 已提交
301 302 303
			assert.equal(result.get(0).name, localEnabledTheme.manifest.name, 'Unexpected extension for @installed query with multiple category.');
			assert.equal(result.get(1).name, localRandom.manifest.name, 'Unexpected extension for @installed query with multiple category.');
			assert.equal(result.get(2).name, localDisabledTheme.manifest.name, 'Unexpected extension for @installed query with multiple category.');
304 305
		});

S
Sandeep Somavarapu 已提交
306
		await testableView.show('@enabled category:themes').then(result => {
307 308 309 310
			assert.equal(result.length, 1, 'Unexpected number of results for @enabled query with category');
			assert.equal(result.get(0).name, localEnabledTheme.manifest.name, 'Unexpected extension for @enabled query with category.');
		});

S
Sandeep Somavarapu 已提交
311
		await testableView.show('@enabled category:"themes"').then(result => {
312 313 314 315
			assert.equal(result.length, 1, 'Unexpected number of results for @enabled query with quoted category');
			assert.equal(result.get(0).name, localEnabledTheme.manifest.name, 'Unexpected extension for @enabled query with quoted category.');
		});

S
Sandeep Somavarapu 已提交
316
		await testableView.show('@enabled category:"programming languages"').then(result => {
317 318 319 320
			assert.equal(result.length, 1, 'Unexpected number of results for @enabled query with quoted category inlcuding space');
			assert.equal(result.get(0).name, localEnabledLanguage.manifest.name, 'Unexpected extension for @enabled query with quoted category including space.');
		});

S
Sandeep Somavarapu 已提交
321
		await testableView.show('@disabled category:themes').then(result => {
322 323 324 325
			assert.equal(result.length, 1, 'Unexpected number of results for @disabled query with category');
			assert.equal(result.get(0).name, localDisabledTheme.manifest.name, 'Unexpected extension for @disabled query with category.');
		});

S
Sandeep Somavarapu 已提交
326
		await testableView.show('@disabled category:"themes"').then(result => {
327 328 329 330
			assert.equal(result.length, 1, 'Unexpected number of results for @disabled query with quoted category');
			assert.equal(result.get(0).name, localDisabledTheme.manifest.name, 'Unexpected extension for @disabled query with quoted category.');
		});

S
Sandeep Somavarapu 已提交
331
		await testableView.show('@disabled category:"programming languages"').then(result => {
332 333 334
			assert.equal(result.length, 1, 'Unexpected number of results for @disabled query with quoted category inlcuding space');
			assert.equal(result.get(0).name, localDisabledLanguage.manifest.name, 'Unexpected extension for @disabled query with quoted category including space.');
		});
R
Ramya Achutha Rao 已提交
335 336 337 338 339
	});

	test('Test @recommended:workspace query', () => {
		const workspaceRecommendedExtensions = [
			workspaceRecommendationA,
340 341
			workspaceRecommendationB,
			configBasedRecommendationA,
R
Ramya Achutha Rao 已提交
342 343 344 345 346 347
		];
		const target = <SinonStub>instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(...workspaceRecommendedExtensions));

		return testableView.show('@recommended:workspace').then(result => {
			assert.ok(target.calledOnce);
			const options: IQueryOptions = target.args[0][0];
348
			assert.equal(options.names!.length, workspaceRecommendedExtensions.length);
R
Ramya Achutha Rao 已提交
349 350
			assert.equal(result.length, workspaceRecommendedExtensions.length);
			for (let i = 0; i < workspaceRecommendedExtensions.length; i++) {
351
				assert.equal(options.names![i], workspaceRecommendedExtensions[i].identifier.id);
S
Sandeep Somavarapu 已提交
352
				assert.equal(result.get(i).identifier.id, workspaceRecommendedExtensions[i].identifier.id);
R
Ramya Achutha Rao 已提交
353 354 355 356 357 358 359 360
			}
		});
	});

	test('Test @recommended query', () => {
		const allRecommendedExtensions = [
			fileBasedRecommendationA,
			fileBasedRecommendationB,
361
			configBasedRecommendationB,
R
Ramya Achutha Rao 已提交
362 363 364 365 366 367 368 369
			otherRecommendationA
		];
		const target = <SinonStub>instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(...allRecommendedExtensions));

		return testableView.show('@recommended').then(result => {
			const options: IQueryOptions = target.args[0][0];

			assert.ok(target.calledOnce);
370
			assert.equal(options.names!.length, allRecommendedExtensions.length);
R
Ramya Achutha Rao 已提交
371 372
			assert.equal(result.length, allRecommendedExtensions.length);
			for (let i = 0; i < allRecommendedExtensions.length; i++) {
373
				assert.equal(options.names![i], allRecommendedExtensions[i].identifier.id);
S
Sandeep Somavarapu 已提交
374
				assert.equal(result.get(i).identifier.id, allRecommendedExtensions[i].identifier.id);
R
Ramya Achutha Rao 已提交
375 376 377 378 379 380 381 382 383
			}
		});
	});


	test('Test @recommended:all query', () => {
		const allRecommendedExtensions = [
			workspaceRecommendationA,
			workspaceRecommendationB,
384
			configBasedRecommendationA,
R
Ramya Achutha Rao 已提交
385 386
			fileBasedRecommendationA,
			fileBasedRecommendationB,
387 388
			configBasedRecommendationB,
			otherRecommendationA,
R
Ramya Achutha Rao 已提交
389 390 391 392 393 394 395
		];
		const target = <SinonStub>instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(...allRecommendedExtensions));

		return testableView.show('@recommended:all').then(result => {
			const options: IQueryOptions = target.args[0][0];

			assert.ok(target.calledOnce);
396
			assert.equal(options.names!.length, allRecommendedExtensions.length);
R
Ramya Achutha Rao 已提交
397 398
			assert.equal(result.length, allRecommendedExtensions.length);
			for (let i = 0; i < allRecommendedExtensions.length; i++) {
399
				assert.equal(options.names![i], allRecommendedExtensions[i].identifier.id);
S
Sandeep Somavarapu 已提交
400
				assert.equal(result.get(i).identifier.id, allRecommendedExtensions[i].identifier.id);
R
Ramya Achutha Rao 已提交
401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418
			}
		});
	});

	test('Test curated list experiment', () => {
		const curatedList = [
			workspaceRecommendationA,
			fileBasedRecommendationA
		];
		const experimentTarget = <SinonStub>instantiationService.stubPromise(IExperimentService, 'getCuratedExtensionsList', curatedList.map(e => e.identifier.id));
		const queryTarget = <SinonStub>instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(...curatedList));

		return testableView.show('curated:mykey').then(result => {
			const curatedKey: string = experimentTarget.args[0][0];
			const options: IQueryOptions = queryTarget.args[0][0];

			assert.ok(experimentTarget.calledOnce);
			assert.ok(queryTarget.calledOnce);
419
			assert.equal(options.names!.length, curatedList.length);
R
Ramya Achutha Rao 已提交
420 421
			assert.equal(result.length, curatedList.length);
			for (let i = 0; i < curatedList.length; i++) {
422
				assert.equal(options.names![i], curatedList[i].identifier.id);
S
Sandeep Somavarapu 已提交
423
				assert.equal(result.get(i).identifier.id, curatedList[i].identifier.id);
R
Ramya Achutha Rao 已提交
424 425 426 427 428
			}
			assert.equal(curatedKey, 'mykey');
		});
	});

R
Ramya Achutha Rao 已提交
429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444
	test('Test search', () => {
		const searchText = 'search-me';
		const results = [
			fileBasedRecommendationA,
			workspaceRecommendationA,
			otherRecommendationA,
			workspaceRecommendationB
		];
		const queryTarget = <SinonStub>instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(...results));
		return testableView.show('search-me').then(result => {
			const options: IQueryOptions = queryTarget.args[0][0];

			assert.ok(queryTarget.calledOnce);
			assert.equal(options.text, searchText);
			assert.equal(result.length, results.length);
			for (let i = 0; i < results.length; i++) {
S
Sandeep Somavarapu 已提交
445
				assert.equal(result.get(i).identifier.id, results[i].identifier.id);
R
Ramya Achutha Rao 已提交
446 447 448 449 450 451
			}
		});
	});

	test('Test preferred search experiment', () => {
		const searchText = 'search-me';
S
Sandeep Somavarapu 已提交
452
		const actual = [
R
Ramya Achutha Rao 已提交
453 454 455 456 457
			fileBasedRecommendationA,
			workspaceRecommendationA,
			otherRecommendationA,
			workspaceRecommendationB
		];
S
Sandeep Somavarapu 已提交
458
		const expected = [
R
Ramya Achutha Rao 已提交
459 460 461 462 463 464
			workspaceRecommendationA,
			workspaceRecommendationB,
			fileBasedRecommendationA,
			otherRecommendationA
		];

S
Sandeep Somavarapu 已提交
465
		const queryTarget = <SinonStub>instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(...actual));
R
Ramya Achutha Rao 已提交
466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491
		const experimentTarget = <SinonStub>instantiationService.stubPromise(IExperimentService, 'getExperimentsByType', [{
			id: 'someId',
			enabled: true,
			state: ExperimentState.Run,
			action: {
				type: ExperimentActionType.ExtensionSearchResults,
				properties: {
					searchText: 'search-me',
					preferredResults: [
						workspaceRecommendationA.identifier.id,
						'something-that-wasnt-in-first-page',
						workspaceRecommendationB.identifier.id
					]
				}
			}
		}]);

		testableView.dispose();
		testableView = instantiationService.createInstance(ExtensionsListView, {});

		return testableView.show('search-me').then(result => {
			const options: IQueryOptions = queryTarget.args[0][0];

			assert.ok(experimentTarget.calledOnce);
			assert.ok(queryTarget.calledOnce);
			assert.equal(options.text, searchText);
S
Sandeep Somavarapu 已提交
492 493
			assert.equal(result.length, expected.length);
			for (let i = 0; i < expected.length; i++) {
S
Sandeep Somavarapu 已提交
494
				assert.equal(result.get(i).identifier.id, expected[i].identifier.id);
R
Ramya Achutha Rao 已提交
495 496 497 498
			}
		});
	});

499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519
	test('Skip preferred search experiment when user defines sort order', () => {
		const searchText = 'search-me';
		const realResults = [
			fileBasedRecommendationA,
			workspaceRecommendationA,
			otherRecommendationA,
			workspaceRecommendationB
		];

		const queryTarget = <SinonStub>instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(...realResults));

		testableView.dispose();
		testableView = instantiationService.createInstance(ExtensionsListView, {});

		return testableView.show('search-me @sort:installs').then(result => {
			const options: IQueryOptions = queryTarget.args[0][0];

			assert.ok(queryTarget.calledOnce);
			assert.equal(options.text, searchText);
			assert.equal(result.length, realResults.length);
			for (let i = 0; i < realResults.length; i++) {
S
Sandeep Somavarapu 已提交
520
				assert.equal(result.get(i).identifier.id, realResults[i].identifier.id);
521 522 523 524
			}
		});
	});

525
	function aLocalExtension(name: string = 'someext', manifest: any = {}, properties: any = {}): ILocalExtension {
526 527
		manifest = { name, publisher: 'pub', version: '1.0.0', ...manifest };
		properties = {
528 529
			type: ExtensionType.User,
			location: URI.file(`pub.${name}`),
530 531 532 533
			identifier: { id: getGalleryExtensionId(manifest.publisher, manifest.name) },
			metadata: { id: getGalleryExtensionId(manifest.publisher, manifest.name), publisherId: manifest.publisher, publisherDisplayName: 'somename' },
			...properties
		};
534
		return <ILocalExtension>Object.create({ manifest, ...properties });
R
Ramya Achutha Rao 已提交
535 536 537
	}

	function aGalleryExtension(name: string, properties: any = {}, galleryExtensionProperties: any = {}, assets: any = {}): IGalleryExtension {
538 539 540
		const galleryExtension = <IGalleryExtension>Object.create({ name, publisher: 'pub', version: '1.0.0', properties: {}, assets: {}, ...properties });
		galleryExtension.properties = { ...galleryExtension.properties, dependencies: [], ...galleryExtensionProperties };
		galleryExtension.assets = { ...galleryExtension.assets, ...assets };
R
Ramya Achutha Rao 已提交
541 542 543 544 545
		galleryExtension.identifier = { id: getGalleryExtensionId(galleryExtension.publisher, galleryExtension.name), uuid: generateUuid() };
		return <IGalleryExtension>galleryExtension;
	}

	function aPage<T>(...objects: T[]): IPager<T> {
546
		return { firstPage: objects, total: objects.length, pageSize: objects.length, getPage: () => null! };
R
Ramya Achutha Rao 已提交
547
	}
548 549 550 551 552 553 554 555 556 557

	function toExtensionDescription(local: ILocalExtension): IExtensionDescription {
		return {
			identifier: new ExtensionIdentifier(local.identifier.id),
			isBuiltin: local.type === ExtensionType.System,
			isUnderDevelopment: false,
			extensionLocation: local.location,
			...local.manifest
		};
	}
R
Ramya Achutha Rao 已提交
558 559
});