Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/contrib/externalUriOpener/test/common/externalUriOpenerService.test.ts
4780 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import assert from 'assert';
7
import { CancellationToken } from '../../../../../base/common/cancellation.js';
8
import { Disposable, DisposableStore } from '../../../../../base/common/lifecycle.js';
9
import { URI } from '../../../../../base/common/uri.js';
10
import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../../base/test/common/utils.js';
11
import { ExternalUriOpenerPriority } from '../../../../../editor/common/languages.js';
12
import { IConfigurationService } from '../../../../../platform/configuration/common/configuration.js';
13
import { TestConfigurationService } from '../../../../../platform/configuration/test/common/testConfigurationService.js';
14
import { TestInstantiationService } from '../../../../../platform/instantiation/test/common/instantiationServiceMock.js';
15
import { IOpenerService } from '../../../../../platform/opener/common/opener.js';
16
import { IPickOptions, IQuickInputService, IQuickPickItem, QuickPickInput } from '../../../../../platform/quickinput/common/quickInput.js';
17
import { ExternalUriOpenerService, IExternalOpenerProvider, IExternalUriOpener } from '../../common/externalUriOpenerService.js';
18
19
20
class MockQuickInputService implements Partial<IQuickInputService> {
21
22
constructor(
23
private readonly pickIndex: number
24
) { }
25
26
public pick<T extends IQuickPickItem>(picks: Promise<QuickPickInput<T>[]> | QuickPickInput<T>[], options?: IPickOptions<T> & { canPickMany: true }, token?: CancellationToken): Promise<T[]>;
27
public pick<T extends IQuickPickItem>(picks: Promise<QuickPickInput<T>[]> | QuickPickInput<T>[], options?: IPickOptions<T> & { canPickMany: false }, token?: CancellationToken): Promise<T>;
28
public async pick<T extends IQuickPickItem>(picks: Promise<QuickPickInput<T>[]> | QuickPickInput<T>[], options?: Omit<IPickOptions<T>, 'canPickMany'>, token?: CancellationToken): Promise<T | undefined> {
29
const resolvedPicks = await picks;
30
const item = resolvedPicks[this.pickIndex];
31
if (item.type === 'separator') {
32
return undefined;
33
}
34
return item;
35
}
36
37
}
38
39
suite('ExternalUriOpenerService', () => {
40
let disposables: DisposableStore;
41
let instantiationService: TestInstantiationService;
42
43
setup(() => {
44
disposables = new DisposableStore();
45
instantiationService = disposables.add(new TestInstantiationService());
46
47
instantiationService.stub(IConfigurationService, new TestConfigurationService());
48
instantiationService.stub(IOpenerService, {
49
registerExternalOpener: () => { return Disposable.None; }
50
});
51
});
52
53
teardown(() => {
54
disposables.dispose();
55
});
56
57
ensureNoDisposablesAreLeakedInTestSuite();
58
59
test('Should not open if there are no openers', async () => {
60
const externalUriOpenerService = disposables.add(instantiationService.createInstance(ExternalUriOpenerService));
61
62
externalUriOpenerService.registerExternalOpenerProvider(new class implements IExternalOpenerProvider {
63
async *getOpeners(_targetUri: URI): AsyncGenerator<IExternalUriOpener> {
64
// noop
65
}
66
});
67
68
const uri = URI.parse('http://contoso.com');
69
const didOpen = await externalUriOpenerService.openExternal(uri.toString(), { sourceUri: uri }, CancellationToken.None);
70
assert.strictEqual(didOpen, false);
71
});
72
73
test('Should prompt if there is at least one enabled opener', async () => {
74
instantiationService.stub(IQuickInputService, new MockQuickInputService(0));
75
76
const externalUriOpenerService = disposables.add(instantiationService.createInstance(ExternalUriOpenerService));
77
78
let openedWithEnabled = false;
79
externalUriOpenerService.registerExternalOpenerProvider(new class implements IExternalOpenerProvider {
80
async *getOpeners(_targetUri: URI): AsyncGenerator<IExternalUriOpener> {
81
yield {
82
id: 'disabled-id',
83
label: 'disabled',
84
canOpen: async () => ExternalUriOpenerPriority.None,
85
openExternalUri: async () => true,
86
};
87
yield {
88
id: 'enabled-id',
89
label: 'enabled',
90
canOpen: async () => ExternalUriOpenerPriority.Default,
91
openExternalUri: async () => {
92
openedWithEnabled = true;
93
return true;
94
}
95
};
96
}
97
});
98
99
const uri = URI.parse('http://contoso.com');
100
const didOpen = await externalUriOpenerService.openExternal(uri.toString(), { sourceUri: uri }, CancellationToken.None);
101
assert.strictEqual(didOpen, true);
102
assert.strictEqual(openedWithEnabled, true);
103
});
104
105
test('Should automatically pick single preferred opener without prompt', async () => {
106
const externalUriOpenerService = disposables.add(instantiationService.createInstance(ExternalUriOpenerService));
107
108
let openedWithPreferred = false;
109
externalUriOpenerService.registerExternalOpenerProvider(new class implements IExternalOpenerProvider {
110
async *getOpeners(_targetUri: URI): AsyncGenerator<IExternalUriOpener> {
111
yield {
112
id: 'other-id',
113
label: 'other',
114
canOpen: async () => ExternalUriOpenerPriority.Default,
115
openExternalUri: async () => {
116
return true;
117
}
118
};
119
yield {
120
id: 'preferred-id',
121
label: 'preferred',
122
canOpen: async () => ExternalUriOpenerPriority.Preferred,
123
openExternalUri: async () => {
124
openedWithPreferred = true;
125
return true;
126
}
127
};
128
}
129
});
130
131
const uri = URI.parse('http://contoso.com');
132
const didOpen = await externalUriOpenerService.openExternal(uri.toString(), { sourceUri: uri }, CancellationToken.None);
133
assert.strictEqual(didOpen, true);
134
assert.strictEqual(openedWithPreferred, true);
135
});
136
});
137
138