@theia/workspace 1.68.0-next.48 → 1.68.0-next.79

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/lib/browser/workspace-frontend-contribution.d.ts.map +1 -1
  2. package/lib/browser/workspace-frontend-contribution.js +3 -0
  3. package/lib/browser/workspace-frontend-contribution.js.map +1 -1
  4. package/lib/browser/workspace-frontend-module.d.ts +1 -0
  5. package/lib/browser/workspace-frontend-module.d.ts.map +1 -1
  6. package/lib/browser/workspace-frontend-module.js +2 -0
  7. package/lib/browser/workspace-frontend-module.js.map +1 -1
  8. package/lib/browser/workspace-trust-dialog.d.ts +13 -0
  9. package/lib/browser/workspace-trust-dialog.d.ts.map +1 -0
  10. package/lib/browser/workspace-trust-dialog.js +66 -0
  11. package/lib/browser/workspace-trust-dialog.js.map +1 -0
  12. package/lib/browser/workspace-trust-service.d.ts +58 -2
  13. package/lib/browser/workspace-trust-service.d.ts.map +1 -1
  14. package/lib/browser/workspace-trust-service.js +177 -37
  15. package/lib/browser/workspace-trust-service.js.map +1 -1
  16. package/lib/browser/workspace-trust-service.spec.js +192 -39
  17. package/lib/browser/workspace-trust-service.spec.js.map +1 -1
  18. package/lib/common/untitled-workspace-service.d.ts +8 -1
  19. package/lib/common/untitled-workspace-service.d.ts.map +1 -1
  20. package/lib/common/untitled-workspace-service.js +21 -2
  21. package/lib/common/untitled-workspace-service.js.map +1 -1
  22. package/package.json +5 -5
  23. package/src/browser/style/index.css +75 -0
  24. package/src/browser/workspace-frontend-contribution.ts +2 -0
  25. package/src/browser/workspace-frontend-module.ts +4 -1
  26. package/src/browser/workspace-trust-dialog.tsx +90 -0
  27. package/src/browser/workspace-trust-service.spec.ts +246 -43
  28. package/src/browser/workspace-trust-service.ts +213 -40
  29. package/src/common/untitled-workspace-service.ts +21 -2
@@ -0,0 +1,90 @@
1
+ // *****************************************************************************
2
+ // Copyright (C) 2026 EclipseSource and others.
3
+ //
4
+ // This program and the accompanying materials are made available under the
5
+ // terms of the Eclipse Public License v. 2.0 which is available at
6
+ // http://www.eclipse.org/legal/epl-2.0.
7
+ //
8
+ // This Source Code may also be made available under the following Secondary
9
+ // Licenses when the conditions for such availability set forth in the Eclipse
10
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ // with the GNU Classpath Exception which is available at
12
+ // https://www.gnu.org/software/classpath/license.html.
13
+ //
14
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
+ // *****************************************************************************
16
+
17
+ import { nls } from '@theia/core';
18
+ import { codicon } from '@theia/core/lib/browser';
19
+ import { ReactDialog } from '@theia/core/lib/browser/dialogs/react-dialog';
20
+ import * as React from '@theia/core/shared/react';
21
+ import URI from '@theia/core/lib/common/uri';
22
+
23
+ export class WorkspaceTrustDialog extends ReactDialog<boolean> {
24
+ protected confirmed = true;
25
+
26
+ constructor(protected readonly folderUris: URI[]) {
27
+ super({
28
+ title: '',
29
+ maxWidth: 500
30
+ });
31
+
32
+ this.node.classList.add('workspace-trust-dialog');
33
+
34
+ this.appendCloseButton(nls.localizeByDefault("No, I don't trust the authors"));
35
+ this.appendAcceptButton(nls.localizeByDefault('Yes, I trust the authors'));
36
+ this.controlPanel.removeChild(this.errorMessageNode);
37
+ }
38
+
39
+ get value(): boolean {
40
+ return this.confirmed;
41
+ }
42
+
43
+ protected override handleEscape(): boolean | void {
44
+ this.confirmed = false;
45
+ this.accept();
46
+ }
47
+
48
+ override close(): void {
49
+ this.confirmed = false;
50
+ this.accept();
51
+ }
52
+
53
+ protected render(): React.ReactNode {
54
+ return (
55
+ <div className="workspace-trust-content">
56
+ <div className="workspace-trust-header">
57
+ <i className={codicon('shield')}></i>
58
+ <div className="workspace-trust-title">
59
+ {nls.localizeByDefault('Do you trust the authors of the files in this folder?')}
60
+ </div>
61
+ </div>
62
+ <div className="workspace-trust-description">
63
+ {nls.localize(
64
+ 'theia/workspace/trustDialogMessage',
65
+ `If you trust the authors, code in this folder may be executed.
66
+
67
+ If not, some features will be disabled.
68
+
69
+ The workspace trust feature is currently under development in Theia; not all features are integrated with workspace trust yet.
70
+ Check the 'Restricted Mode' indicator in the status bar for details.`
71
+ )}
72
+ </div>
73
+ {this.folderUris.length > 0 && (
74
+ <div className="workspace-trust-folder">
75
+ <ul className="workspace-trust-folder-list">
76
+ {this.folderUris.map(uri => {
77
+ const stringified = uri.path.fsPath();
78
+ return (
79
+ <li key={stringified}>
80
+ {stringified}
81
+ </li>
82
+ );
83
+ })}
84
+ </ul>
85
+ </div>
86
+ )}
87
+ </div>
88
+ );
89
+ }
90
+ }
@@ -18,7 +18,14 @@ import { expect } from 'chai';
18
18
  import * as sinon from 'sinon';
19
19
  import { PreferenceChange, PreferenceScope } from '@theia/core/lib/common/preferences';
20
20
  import { WorkspaceTrustService } from './workspace-trust-service';
21
- import { WORKSPACE_TRUST_EMPTY_WINDOW, WORKSPACE_TRUST_TRUSTED_FOLDERS } from '../common/workspace-trust-preferences';
21
+ import {
22
+ WORKSPACE_TRUST_EMPTY_WINDOW,
23
+ WORKSPACE_TRUST_ENABLED,
24
+ WORKSPACE_TRUST_STARTUP_PROMPT,
25
+ WORKSPACE_TRUST_TRUSTED_FOLDERS,
26
+ WorkspaceTrustPrompt
27
+ } from '../common/workspace-trust-preferences';
28
+ import URI from '@theia/core/lib/common/uri';
22
29
 
23
30
  class TestableWorkspaceTrustService extends WorkspaceTrustService {
24
31
  public async testHandlePreferenceChange(change: PreferenceChange): Promise<void> {
@@ -29,7 +36,7 @@ class TestableWorkspaceTrustService extends WorkspaceTrustService {
29
36
  return this.handleWorkspaceChanged();
30
37
  }
31
38
 
32
- public setCurrentTrust(trust: boolean): void {
39
+ public setCurrentTrust(trust: boolean | undefined): void {
33
40
  this.currentTrust = trust;
34
41
  }
35
42
 
@@ -40,6 +47,10 @@ class TestableWorkspaceTrustService extends WorkspaceTrustService {
40
47
  public override isWorkspaceTrustResolved(): boolean {
41
48
  return super.isWorkspaceTrustResolved();
42
49
  }
50
+
51
+ public async testCalculateWorkspaceTrust(): Promise<boolean | undefined> {
52
+ return this.calculateWorkspaceTrust();
53
+ }
43
54
  }
44
55
 
45
56
  describe('WorkspaceTrustService', () => {
@@ -49,6 +60,199 @@ describe('WorkspaceTrustService', () => {
49
60
  service = new TestableWorkspaceTrustService();
50
61
  });
51
62
 
63
+ afterEach(() => {
64
+ sinon.restore();
65
+ });
66
+
67
+ describe('calculateWorkspaceTrust', () => {
68
+ let workspaceTrustPrefStub: { [key: string]: unknown };
69
+ let workspaceServiceStub: {
70
+ tryGetRoots: () => Array<{ resource: URI }>;
71
+ workspace: { resource: URI } | undefined;
72
+ saved: boolean;
73
+ };
74
+ let untitledWorkspaceServiceStub: {
75
+ isUntitledWorkspace: (uri?: URI, configDirUri?: URI) => boolean;
76
+ };
77
+ let envVariablesServerStub: {
78
+ getConfigDirUri: () => Promise<string>;
79
+ };
80
+
81
+ beforeEach(() => {
82
+ workspaceTrustPrefStub = {
83
+ [WORKSPACE_TRUST_ENABLED]: true,
84
+ [WORKSPACE_TRUST_EMPTY_WINDOW]: false,
85
+ [WORKSPACE_TRUST_STARTUP_PROMPT]: WorkspaceTrustPrompt.NEVER,
86
+ [WORKSPACE_TRUST_TRUSTED_FOLDERS]: []
87
+ };
88
+ workspaceServiceStub = {
89
+ tryGetRoots: () => [],
90
+ workspace: undefined,
91
+ saved: false
92
+ };
93
+ untitledWorkspaceServiceStub = {
94
+ isUntitledWorkspace: () => false
95
+ };
96
+ envVariablesServerStub = {
97
+ getConfigDirUri: async () => 'file:///home/user/.theia'
98
+ };
99
+
100
+ (service as unknown as { workspaceTrustPref: typeof workspaceTrustPrefStub }).workspaceTrustPref = workspaceTrustPrefStub;
101
+ (service as unknown as { workspaceService: typeof workspaceServiceStub }).workspaceService = workspaceServiceStub;
102
+ (service as unknown as { untitledWorkspaceService: typeof untitledWorkspaceServiceStub }).untitledWorkspaceService = untitledWorkspaceServiceStub;
103
+ (service as unknown as { envVariablesServer: typeof envVariablesServerStub }).envVariablesServer = envVariablesServerStub;
104
+ });
105
+
106
+ it('should return true when trust is disabled', async () => {
107
+ workspaceTrustPrefStub[WORKSPACE_TRUST_ENABLED] = false;
108
+
109
+ expect(await service.testCalculateWorkspaceTrust()).to.be.true;
110
+ });
111
+
112
+ describe('empty workspace', () => {
113
+ it('should return emptyWindow setting when no workspace is open', async () => {
114
+ workspaceServiceStub.workspace = undefined;
115
+ workspaceTrustPrefStub[WORKSPACE_TRUST_EMPTY_WINDOW] = true;
116
+
117
+ expect(await service.testCalculateWorkspaceTrust()).to.be.true;
118
+ });
119
+
120
+ it('should return false when emptyWindow is false and no workspace', async () => {
121
+ workspaceServiceStub.workspace = undefined;
122
+ workspaceTrustPrefStub[WORKSPACE_TRUST_EMPTY_WINDOW] = false;
123
+
124
+ expect(await service.testCalculateWorkspaceTrust()).to.be.false;
125
+ });
126
+
127
+ it('should return emptyWindow setting for untitled workspace with no folders', async () => {
128
+ workspaceServiceStub.workspace = { resource: new URI('file:///home/user/.theia/workspaces/Untitled-123.theia-workspace') };
129
+ workspaceServiceStub.tryGetRoots = () => [];
130
+ untitledWorkspaceServiceStub.isUntitledWorkspace = () => true;
131
+ workspaceTrustPrefStub[WORKSPACE_TRUST_EMPTY_WINDOW] = true;
132
+
133
+ expect(await service.testCalculateWorkspaceTrust()).to.be.true;
134
+ });
135
+
136
+ it('should not treat saved workspace with no folders as empty', async () => {
137
+ workspaceServiceStub.workspace = { resource: new URI('file:///home/user/my.theia-workspace') };
138
+ workspaceServiceStub.tryGetRoots = () => [];
139
+ workspaceServiceStub.saved = true;
140
+ untitledWorkspaceServiceStub.isUntitledWorkspace = () => false;
141
+ workspaceTrustPrefStub[WORKSPACE_TRUST_EMPTY_WINDOW] = true;
142
+
143
+ // Should return false because saved workspace with 0 folders is not "empty"
144
+ // and the workspace file is not trusted
145
+ expect(await service.testCalculateWorkspaceTrust()).to.be.false;
146
+ });
147
+ });
148
+
149
+ describe('single-root workspace', () => {
150
+ it('should return true when folder is in trusted folders', async () => {
151
+ workspaceTrustPrefStub[WORKSPACE_TRUST_TRUSTED_FOLDERS] = ['file:///home/user/project'];
152
+ workspaceServiceStub.workspace = { resource: new URI('file:///home/user/project') };
153
+ workspaceServiceStub.tryGetRoots = () => [
154
+ { resource: new URI('file:///home/user/project') }
155
+ ];
156
+
157
+ expect(await service.testCalculateWorkspaceTrust()).to.be.true;
158
+ });
159
+
160
+ it('should return true when parent folder is trusted', async () => {
161
+ workspaceTrustPrefStub[WORKSPACE_TRUST_TRUSTED_FOLDERS] = ['file:///home/user'];
162
+ workspaceServiceStub.workspace = { resource: new URI('file:///home/user/project') };
163
+ workspaceServiceStub.tryGetRoots = () => [
164
+ { resource: new URI('file:///home/user/project') }
165
+ ];
166
+
167
+ expect(await service.testCalculateWorkspaceTrust()).to.be.true;
168
+ });
169
+
170
+ it('should return false when folder is not trusted', async () => {
171
+ workspaceTrustPrefStub[WORKSPACE_TRUST_TRUSTED_FOLDERS] = ['file:///home/other'];
172
+ workspaceServiceStub.workspace = { resource: new URI('file:///home/user/project') };
173
+ workspaceServiceStub.tryGetRoots = () => [
174
+ { resource: new URI('file:///home/user/project') }
175
+ ];
176
+
177
+ expect(await service.testCalculateWorkspaceTrust()).to.be.false;
178
+ });
179
+ });
180
+
181
+ describe('multi-root workspace', () => {
182
+ it('should return true when all folders are trusted', async () => {
183
+ workspaceTrustPrefStub[WORKSPACE_TRUST_TRUSTED_FOLDERS] = [
184
+ 'file:///home/user/project1',
185
+ 'file:///home/user/project2'
186
+ ];
187
+ workspaceServiceStub.workspace = { resource: new URI('file:///home/user/my.theia-workspace') };
188
+ workspaceServiceStub.tryGetRoots = () => [
189
+ { resource: new URI('file:///home/user/project1') },
190
+ { resource: new URI('file:///home/user/project2') }
191
+ ];
192
+
193
+ expect(await service.testCalculateWorkspaceTrust()).to.be.true;
194
+ });
195
+
196
+ it('should return false when one folder is not trusted', async () => {
197
+ workspaceTrustPrefStub[WORKSPACE_TRUST_TRUSTED_FOLDERS] = ['file:///home/user/project1'];
198
+ workspaceServiceStub.workspace = { resource: new URI('file:///home/user/my.theia-workspace') };
199
+ workspaceServiceStub.tryGetRoots = () => [
200
+ { resource: new URI('file:///home/user/project1') },
201
+ { resource: new URI('file:///home/user/project2') }
202
+ ];
203
+
204
+ expect(await service.testCalculateWorkspaceTrust()).to.be.false;
205
+ });
206
+
207
+ it('should return true when parent folder covers all roots', async () => {
208
+ workspaceTrustPrefStub[WORKSPACE_TRUST_TRUSTED_FOLDERS] = ['file:///home/user'];
209
+ workspaceServiceStub.workspace = { resource: new URI('file:///home/user/my.theia-workspace') };
210
+ workspaceServiceStub.tryGetRoots = () => [
211
+ { resource: new URI('file:///home/user/project1') },
212
+ { resource: new URI('file:///home/user/project2') }
213
+ ];
214
+
215
+ expect(await service.testCalculateWorkspaceTrust()).to.be.true;
216
+ });
217
+ });
218
+
219
+ describe('saved workspace file trust', () => {
220
+ it('should require workspace file to be trusted for saved workspaces', async () => {
221
+ // Folder is trusted but workspace file location is not
222
+ workspaceTrustPrefStub[WORKSPACE_TRUST_TRUSTED_FOLDERS] = ['file:///home/user/project'];
223
+ workspaceServiceStub.workspace = { resource: new URI('file:///other/location/my.theia-workspace') };
224
+ workspaceServiceStub.saved = true;
225
+ workspaceServiceStub.tryGetRoots = () => [
226
+ { resource: new URI('file:///home/user/project') }
227
+ ];
228
+
229
+ expect(await service.testCalculateWorkspaceTrust()).to.be.false;
230
+ });
231
+
232
+ it('should return true when both folder and workspace file are trusted', async () => {
233
+ workspaceTrustPrefStub[WORKSPACE_TRUST_TRUSTED_FOLDERS] = ['file:///home/user'];
234
+ workspaceServiceStub.workspace = { resource: new URI('file:///home/user/my.theia-workspace') };
235
+ workspaceServiceStub.saved = true;
236
+ workspaceServiceStub.tryGetRoots = () => [
237
+ { resource: new URI('file:///home/user/project') }
238
+ ];
239
+
240
+ expect(await service.testCalculateWorkspaceTrust()).to.be.true;
241
+ });
242
+
243
+ it('should not require workspace file trust for unsaved workspaces', async () => {
244
+ workspaceTrustPrefStub[WORKSPACE_TRUST_TRUSTED_FOLDERS] = ['file:///home/user/project'];
245
+ workspaceServiceStub.workspace = { resource: new URI('file:///tmp/untitled.theia-workspace') };
246
+ workspaceServiceStub.saved = false;
247
+ workspaceServiceStub.tryGetRoots = () => [
248
+ { resource: new URI('file:///home/user/project') }
249
+ ];
250
+
251
+ expect(await service.testCalculateWorkspaceTrust()).to.be.true;
252
+ });
253
+ });
254
+ });
255
+
52
256
  describe('handleWorkspaceChanged', () => {
53
257
  let resolveWorkspaceTrustStub: sinon.SinonStub;
54
258
  let getWorkspaceTrustStub: sinon.SinonStub;
@@ -63,10 +267,6 @@ describe('WorkspaceTrustService', () => {
63
267
  );
64
268
  });
65
269
 
66
- afterEach(() => {
67
- sinon.restore();
68
- });
69
-
70
270
  it('should reset trust state when workspace changes', async () => {
71
271
  service.setCurrentTrust(true);
72
272
 
@@ -103,36 +303,30 @@ describe('WorkspaceTrustService', () => {
103
303
  });
104
304
 
105
305
  describe('handlePreferenceChange', () => {
106
- let isWorkspaceInTrustedFoldersStub: sinon.SinonStub;
306
+ let areAllWorkspaceUrisTrustedStub: sinon.SinonStub;
107
307
  let setWorkspaceTrustStub: sinon.SinonStub;
308
+ let isEmptyWorkspaceStub: sinon.SinonStub;
108
309
  let workspaceTrustPrefStub: { [key: string]: unknown };
109
- let workspaceServiceStub: { workspace: unknown };
110
310
 
111
311
  beforeEach(() => {
112
- isWorkspaceInTrustedFoldersStub = sinon.stub(service as unknown as { isWorkspaceInTrustedFolders: () => boolean }, 'isWorkspaceInTrustedFolders');
312
+ areAllWorkspaceUrisTrustedStub = sinon.stub(service as unknown as { areAllWorkspaceUrisTrusted: () => Promise<boolean> }, 'areAllWorkspaceUrisTrusted');
113
313
  setWorkspaceTrustStub = sinon.stub(service, 'setWorkspaceTrust');
314
+ isEmptyWorkspaceStub = sinon.stub(service as unknown as { isEmptyWorkspace: () => Promise<boolean> }, 'isEmptyWorkspace');
114
315
  // Mock workspaceTrustPref - default emptyWindow to false so trusted folders logic runs
115
316
  workspaceTrustPrefStub = { [WORKSPACE_TRUST_EMPTY_WINDOW]: false };
116
317
  (service as unknown as { workspaceTrustPref: { [key: string]: unknown } }).workspaceTrustPref = workspaceTrustPrefStub;
117
- // Mock workspaceService with a workspace (non-empty)
118
- workspaceServiceStub = { workspace: { resource: { toString: () => 'file:///some/workspace' } } };
119
- (service as unknown as { workspaceService: { workspace: unknown } }).workspaceService = workspaceServiceStub;
120
- });
121
-
122
- afterEach(() => {
123
- sinon.restore();
318
+ // Default to non-empty workspace
319
+ isEmptyWorkspaceStub.resolves(false);
124
320
  });
125
321
 
126
- it('should update trust to true when folder is added to trustedFolders', async () => {
322
+ it('should update trust to true when all workspace URIs become trusted', async () => {
127
323
  service.setCurrentTrust(false);
128
- isWorkspaceInTrustedFoldersStub.returns(true);
324
+ areAllWorkspaceUrisTrustedStub.resolves(true);
129
325
 
130
326
  const change: PreferenceChange = {
131
327
  preferenceName: WORKSPACE_TRUST_TRUSTED_FOLDERS,
132
328
  scope: PreferenceScope.User,
133
329
  domain: [],
134
- newValue: ['/some/path'],
135
- oldValue: [],
136
330
  affects: () => true
137
331
  };
138
332
 
@@ -141,16 +335,14 @@ describe('WorkspaceTrustService', () => {
141
335
  expect(setWorkspaceTrustStub.calledOnceWith(true)).to.be.true;
142
336
  });
143
337
 
144
- it('should update trust to false when folder is removed from trustedFolders', async () => {
338
+ it('should update trust to false when not all workspace URIs are trusted', async () => {
145
339
  service.setCurrentTrust(true);
146
- isWorkspaceInTrustedFoldersStub.returns(false);
340
+ areAllWorkspaceUrisTrustedStub.resolves(false);
147
341
 
148
342
  const change: PreferenceChange = {
149
343
  preferenceName: WORKSPACE_TRUST_TRUSTED_FOLDERS,
150
344
  scope: PreferenceScope.User,
151
345
  domain: [],
152
- newValue: [],
153
- oldValue: ['/some/path'],
154
346
  affects: () => true
155
347
  };
156
348
 
@@ -159,16 +351,14 @@ describe('WorkspaceTrustService', () => {
159
351
  expect(setWorkspaceTrustStub.calledOnceWith(false)).to.be.true;
160
352
  });
161
353
 
162
- it('should not update trust when trustedFolders change does not affect current workspace', async () => {
354
+ it('should not update trust when trustedFolders change does not affect trust status', async () => {
163
355
  service.setCurrentTrust(false);
164
- isWorkspaceInTrustedFoldersStub.returns(false);
356
+ areAllWorkspaceUrisTrustedStub.resolves(false);
165
357
 
166
358
  const change: PreferenceChange = {
167
359
  preferenceName: WORKSPACE_TRUST_TRUSTED_FOLDERS,
168
360
  scope: PreferenceScope.User,
169
361
  domain: [],
170
- newValue: ['/other/path'],
171
- oldValue: [],
172
362
  affects: () => true
173
363
  };
174
364
 
@@ -179,20 +369,18 @@ describe('WorkspaceTrustService', () => {
179
369
 
180
370
  describe('emptyWindow setting changes', () => {
181
371
  beforeEach(() => {
182
- // Reset workspace to undefined for empty window tests
183
- workspaceServiceStub.workspace = undefined;
372
+ // Reset to empty workspace for empty window tests
373
+ isEmptyWorkspaceStub.resolves(true);
184
374
  });
185
375
 
186
376
  it('should update trust to true when emptyWindow setting changes to true for empty window', async () => {
187
377
  service.setCurrentTrust(false);
188
- workspaceServiceStub.workspace = undefined;
378
+ workspaceTrustPrefStub[WORKSPACE_TRUST_EMPTY_WINDOW] = true;
189
379
 
190
380
  const change: PreferenceChange = {
191
381
  preferenceName: WORKSPACE_TRUST_EMPTY_WINDOW,
192
382
  scope: PreferenceScope.User,
193
383
  domain: [],
194
- newValue: true,
195
- oldValue: false,
196
384
  affects: () => true
197
385
  };
198
386
 
@@ -203,14 +391,11 @@ describe('WorkspaceTrustService', () => {
203
391
 
204
392
  it('should update trust to false when emptyWindow setting changes to false for empty window', async () => {
205
393
  service.setCurrentTrust(true);
206
- workspaceServiceStub.workspace = undefined;
207
394
 
208
395
  const change: PreferenceChange = {
209
396
  preferenceName: WORKSPACE_TRUST_EMPTY_WINDOW,
210
397
  scope: PreferenceScope.User,
211
398
  domain: [],
212
- newValue: false,
213
- oldValue: true,
214
399
  affects: () => true
215
400
  };
216
401
 
@@ -219,16 +404,14 @@ describe('WorkspaceTrustService', () => {
219
404
  expect(setWorkspaceTrustStub.calledOnceWith(false)).to.be.true;
220
405
  });
221
406
 
222
- it('should not update trust when emptyWindow setting changes but workspace is open', async () => {
407
+ it('should not update trust when emptyWindow setting changes but workspace has roots', async () => {
223
408
  service.setCurrentTrust(false);
224
- workspaceServiceStub.workspace = { resource: { toString: () => 'file:///some/path' } };
409
+ isEmptyWorkspaceStub.resolves(false);
225
410
 
226
411
  const change: PreferenceChange = {
227
412
  preferenceName: WORKSPACE_TRUST_EMPTY_WINDOW,
228
413
  scope: PreferenceScope.User,
229
414
  domain: [],
230
- newValue: true,
231
- oldValue: false,
232
415
  affects: () => true
233
416
  };
234
417
 
@@ -239,14 +422,34 @@ describe('WorkspaceTrustService', () => {
239
422
 
240
423
  it('should not update trust when emptyWindow setting changes but trust already matches', async () => {
241
424
  service.setCurrentTrust(true);
242
- workspaceServiceStub.workspace = undefined;
425
+ workspaceTrustPrefStub[WORKSPACE_TRUST_EMPTY_WINDOW] = true;
243
426
 
244
427
  const change: PreferenceChange = {
245
428
  preferenceName: WORKSPACE_TRUST_EMPTY_WINDOW,
246
429
  scope: PreferenceScope.User,
247
430
  domain: [],
248
- newValue: true,
249
- oldValue: false,
431
+ affects: () => true
432
+ };
433
+
434
+ await service.testHandlePreferenceChange(change);
435
+
436
+ expect(setWorkspaceTrustStub.called).to.be.false;
437
+ });
438
+ });
439
+
440
+ describe('trustedFolders change for empty window with emptyWindow enabled', () => {
441
+ beforeEach(() => {
442
+ isEmptyWorkspaceStub.resolves(true);
443
+ workspaceTrustPrefStub[WORKSPACE_TRUST_EMPTY_WINDOW] = true;
444
+ });
445
+
446
+ it('should not change trust when trustedFolders change for empty window with emptyWindow enabled', async () => {
447
+ service.setCurrentTrust(true);
448
+
449
+ const change: PreferenceChange = {
450
+ preferenceName: WORKSPACE_TRUST_TRUSTED_FOLDERS,
451
+ scope: PreferenceScope.User,
452
+ domain: [],
250
453
  affects: () => true
251
454
  };
252
455