Path: blob/main/src/vs/workbench/services/dialogs/test/electron-browser/fileDialogService.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 * as sinon from 'sinon';7import { Schemas } from '../../../../../base/common/network.js';8import { URI } from '../../../../../base/common/uri.js';9import { mock } from '../../../../../base/test/common/mock.js';10import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../../base/test/common/utils.js';11import { ICodeEditorService } from '../../../../../editor/browser/services/codeEditorService.js';12import { ILanguageService } from '../../../../../editor/common/languages/language.js';13import { ICommandService } from '../../../../../platform/commands/common/commands.js';14import { IConfigurationService } from '../../../../../platform/configuration/common/configuration.js';15import { TestConfigurationService } from '../../../../../platform/configuration/test/common/testConfigurationService.js';16import { IDialogService, IFileDialogService, IOpenDialogOptions, ISaveDialogOptions } from '../../../../../platform/dialogs/common/dialogs.js';17import { IFileService } from '../../../../../platform/files/common/files.js';18import { IInstantiationService } from '../../../../../platform/instantiation/common/instantiation.js';19import { TestInstantiationService } from '../../../../../platform/instantiation/test/common/instantiationServiceMock.js';20import { ILabelService } from '../../../../../platform/label/common/label.js';21import { ILogService } from '../../../../../platform/log/common/log.js';22import { INativeHostService } from '../../../../../platform/native/common/native.js';23import { IOpenerService } from '../../../../../platform/opener/common/opener.js';24import { IWorkspaceContextService } from '../../../../../platform/workspace/common/workspace.js';25import { IWorkspacesService } from '../../../../../platform/workspaces/common/workspaces.js';26import { ISimpleFileDialog } from '../../browser/simpleFileDialog.js';27import { FileDialogService } from '../../electron-browser/fileDialogService.js';28import { IEditorService } from '../../../editor/common/editorService.js';29import { BrowserWorkbenchEnvironmentService } from '../../../environment/browser/environmentService.js';30import { IWorkbenchEnvironmentService } from '../../../environment/common/environmentService.js';31import { IHistoryService } from '../../../history/common/history.js';32import { IHostService } from '../../../host/browser/host.js';33import { IPathService } from '../../../path/common/pathService.js';34import { BrowserWorkspaceEditingService } from '../../../workspaces/browser/workspaceEditingService.js';35import { IWorkspaceEditingService } from '../../../workspaces/common/workspaceEditing.js';36import { workbenchInstantiationService } from '../../../../test/browser/workbenchTestServices.js';3738class TestFileDialogService extends FileDialogService {39constructor(40private simple: ISimpleFileDialog,41@IHostService hostService: IHostService,42@IWorkspaceContextService contextService: IWorkspaceContextService,43@IHistoryService historyService: IHistoryService,44@IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService,45@IInstantiationService instantiationService: IInstantiationService,46@IConfigurationService configurationService: IConfigurationService,47@IFileService fileService: IFileService,48@IOpenerService openerService: IOpenerService,49@INativeHostService nativeHostService: INativeHostService,50@IDialogService dialogService: IDialogService,51@ILanguageService languageService: ILanguageService,52@IWorkspacesService workspacesService: IWorkspacesService,53@ILabelService labelService: ILabelService,54@IPathService pathService: IPathService,55@ICommandService commandService: ICommandService,56@IEditorService editorService: IEditorService,57@ICodeEditorService codeEditorService: ICodeEditorService,58@ILogService logService: ILogService59) {60super(hostService, contextService, historyService, environmentService, instantiationService, configurationService, fileService,61openerService, nativeHostService, dialogService, languageService, workspacesService, labelService, pathService, commandService, editorService, codeEditorService, logService);62}6364protected override getSimpleFileDialog() {65if (this.simple) {66return this.simple;67} else {68return super.getSimpleFileDialog();69}70}71}7273suite('FileDialogService', function () {7475let instantiationService: TestInstantiationService;76const disposables = ensureNoDisposablesAreLeakedInTestSuite();77const testFile: URI = URI.file('/test/file');7879setup(async function () {80disposables.add(instantiationService = workbenchInstantiationService(undefined, disposables));81const configurationService = new TestConfigurationService();82await configurationService.setUserConfiguration('files', { simpleDialog: { enable: true } });83instantiationService.stub(IConfigurationService, configurationService);8485});8687test('Local - open/save workspaces availableFilesystems', async function () {88class TestSimpleFileDialog implements ISimpleFileDialog {89async showOpenDialog(options: IOpenDialogOptions): Promise<URI | undefined> {90assert.strictEqual(options.availableFileSystems?.length, 1);91assert.strictEqual(options.availableFileSystems[0], Schemas.file);92return testFile;93}94async showSaveDialog(options: ISaveDialogOptions): Promise<URI | undefined> {95assert.strictEqual(options.availableFileSystems?.length, 1);96assert.strictEqual(options.availableFileSystems[0], Schemas.file);97return testFile;98}99dispose(): void { }100}101102const dialogService = instantiationService.createInstance(TestFileDialogService, new TestSimpleFileDialog());103instantiationService.set(IFileDialogService, dialogService);104const workspaceService: IWorkspaceEditingService = disposables.add(instantiationService.createInstance(BrowserWorkspaceEditingService));105assert.strictEqual((await workspaceService.pickNewWorkspacePath())?.path.startsWith(testFile.path), true);106assert.strictEqual(await dialogService.pickWorkspaceAndOpen({}), undefined);107});108109test('Virtual - open/save workspaces availableFilesystems', async function () {110class TestSimpleFileDialog {111async showOpenDialog(options: IOpenDialogOptions): Promise<URI | undefined> {112assert.strictEqual(options.availableFileSystems?.length, 1);113assert.strictEqual(options.availableFileSystems[0], Schemas.file);114return testFile;115}116async showSaveDialog(options: ISaveDialogOptions): Promise<URI | undefined> {117assert.strictEqual(options.availableFileSystems?.length, 1);118assert.strictEqual(options.availableFileSystems[0], Schemas.file);119return testFile;120}121dispose(): void { }122}123124instantiationService.stub(IPathService, new class {125defaultUriScheme: string = 'vscode-virtual-test';126userHome = async () => URI.file('/user/home');127} as IPathService);128const dialogService = instantiationService.createInstance(TestFileDialogService, new TestSimpleFileDialog());129instantiationService.set(IFileDialogService, dialogService);130const workspaceService: IWorkspaceEditingService = disposables.add(instantiationService.createInstance(BrowserWorkspaceEditingService));131assert.strictEqual((await workspaceService.pickNewWorkspacePath())?.path.startsWith(testFile.path), true);132assert.strictEqual(await dialogService.pickWorkspaceAndOpen({}), undefined);133});134135test('Remote - open/save workspaces availableFilesystems', async function () {136class TestSimpleFileDialog implements ISimpleFileDialog {137async showOpenDialog(options: IOpenDialogOptions): Promise<URI | undefined> {138assert.strictEqual(options.availableFileSystems?.length, 2);139assert.strictEqual(options.availableFileSystems[0], Schemas.vscodeRemote);140assert.strictEqual(options.availableFileSystems[1], Schemas.file);141return testFile;142}143async showSaveDialog(options: ISaveDialogOptions): Promise<URI | undefined> {144assert.strictEqual(options.availableFileSystems?.length, 2);145assert.strictEqual(options.availableFileSystems[0], Schemas.vscodeRemote);146assert.strictEqual(options.availableFileSystems[1], Schemas.file);147return testFile;148}149dispose(): void { }150}151152instantiationService.set(IWorkbenchEnvironmentService, new class extends mock<BrowserWorkbenchEnvironmentService>() {153override get remoteAuthority() {154return 'testRemote';155}156});157instantiationService.stub(IPathService, new class {158defaultUriScheme: string = Schemas.vscodeRemote;159userHome = async () => URI.file('/user/home');160} as IPathService);161const dialogService = instantiationService.createInstance(TestFileDialogService, new TestSimpleFileDialog());162instantiationService.set(IFileDialogService, dialogService);163const workspaceService: IWorkspaceEditingService = disposables.add(instantiationService.createInstance(BrowserWorkspaceEditingService));164assert.strictEqual((await workspaceService.pickNewWorkspacePath())?.path.startsWith(testFile.path), true);165assert.strictEqual(await dialogService.pickWorkspaceAndOpen({}), undefined);166});167168test('Remote - filters default files/folders to RA (#195938)', async function () {169class TestSimpleFileDialog implements ISimpleFileDialog {170async showOpenDialog(): Promise<URI | undefined> {171return testFile;172}173async showSaveDialog(): Promise<URI | undefined> {174return testFile;175}176dispose(): void { }177}178instantiationService.set(IWorkbenchEnvironmentService, new class extends mock<BrowserWorkbenchEnvironmentService>() {179override get remoteAuthority() {180return 'testRemote';181}182});183instantiationService.stub(IPathService, new class {184defaultUriScheme: string = Schemas.vscodeRemote;185userHome = async () => URI.file('/user/home');186} as IPathService);187188189const dialogService = instantiationService.createInstance(TestFileDialogService, new TestSimpleFileDialog());190const historyService = instantiationService.get(IHistoryService);191const getLastActiveWorkspaceRoot = sinon.spy(historyService, 'getLastActiveWorkspaceRoot');192const getLastActiveFile = sinon.spy(historyService, 'getLastActiveFile');193194await dialogService.defaultFilePath();195assert.deepStrictEqual(getLastActiveFile.args, [[Schemas.vscodeRemote, 'testRemote']]);196assert.deepStrictEqual(getLastActiveWorkspaceRoot.args, [[Schemas.vscodeRemote, 'testRemote']]);197198await dialogService.defaultFolderPath();199assert.deepStrictEqual(getLastActiveWorkspaceRoot.args[1], [Schemas.vscodeRemote, 'testRemote']);200});201});202203204