44import * as assert from 'node:assert' ;
55import * as sinon from 'sinon' ;
66import * as typeMoq from 'typemoq' ;
7- import { GlobalEnvironmentVariableCollection , Uri , window , workspace } from 'vscode' ;
7+ import { GlobalEnvironmentVariableCollection , Uri , workspace } from 'vscode' ;
88import { EnvVarManager } from '../../features/execution/envVariableManager' ;
99import { TerminalEnvVarInjector } from '../../features/terminal/terminalEnvVarInjector' ;
1010import * as persistentState from '../../common/persistentState' ;
1111import * as workspaceApis from '../../common/workspace.apis' ;
12+ import * as windowApis from '../../common/window.apis' ;
1213import { Common } from '../../common/localize' ;
1314
1415interface MockScopedCollection {
@@ -22,7 +23,6 @@ suite('TerminalEnvVarInjector Notification Tests', () => {
2223 let envVarManager : typeMoq . IMock < EnvVarManager > ;
2324 let injector : TerminalEnvVarInjector ;
2425 let mockScopedCollection : MockScopedCollection ;
25- let mockGetGlobalPersistentState : sinon . SinonStub ;
2626 let mockState : { get : sinon . SinonStub ; set : sinon . SinonStub ; clear : sinon . SinonStub } ;
2727 let mockGetConfiguration : sinon . SinonStub ;
2828 let mockGetWorkspaceFolder : sinon . SinonStub ;
@@ -63,23 +63,25 @@ suite('TerminalEnvVarInjector Notification Tests', () => {
6363 set : sinon . stub ( ) . resolves ( ) ,
6464 clear : sinon . stub ( ) . resolves ( ) ,
6565 } ;
66- mockGetGlobalPersistentState = sinon . stub ( persistentState , 'getGlobalPersistentState' ) . resolves ( mockState ) ;
66+ sinon . stub ( persistentState , 'getGlobalPersistentState' ) . resolves ( mockState ) ;
6767
6868 // Setup workspace API mocks
6969 mockGetConfiguration = sinon . stub ( workspaceApis , 'getConfiguration' ) ;
7070 mockGetWorkspaceFolder = sinon . stub ( workspaceApis , 'getWorkspaceFolder' ) ;
7171
72- // Setup window. showInformationMessage mock
73- mockShowInformationMessage = sinon . stub ( window , 'showInformationMessage' ) . resolves ( undefined ) ;
72+ // Setup showInformationMessage mock
73+ mockShowInformationMessage = sinon . stub ( windowApis , 'showInformationMessage' ) . resolves ( undefined ) ;
7474
75- // Setup environment variable change event handler
75+ // Setup environment variable change event handler - will be overridden in tests
7676 envVarManager
7777 . setup ( ( m ) => m . onDidChangeEnvironmentVariables )
78- . returns ( ( handler ) => {
79- envVarChangeHandler = handler ;
80- // eslint-disable-next-line @typescript-eslint/no-explicit-any
81- return { dispose : ( ) => { } } as any ;
82- } ) ;
78+ . returns (
79+ ( ) =>
80+ ( {
81+ dispose : ( ) => { } ,
82+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
83+ } as any ) ,
84+ ) ;
8385 } ) ;
8486
8587 teardown ( ( ) => {
@@ -91,6 +93,27 @@ suite('TerminalEnvVarInjector Notification Tests', () => {
9193 // Arrange - user has not dismissed the notification before
9294 mockState . get . resolves ( false ) ;
9395
96+ // Setup environment variable change handler to capture it
97+ envVarManager . reset ( ) ;
98+ envVarCollection . reset ( ) ;
99+
100+ // Re-setup scoped collection after reset
101+ envVarCollection
102+ . setup ( ( x ) => x . getScoped ( typeMoq . It . isAny ( ) ) )
103+ . returns (
104+ ( ) => mockScopedCollection as unknown as ReturnType < GlobalEnvironmentVariableCollection [ 'getScoped' ] > ,
105+ ) ;
106+ envVarCollection . setup ( ( x ) => x . clear ( ) ) . returns ( ( ) => { } ) ;
107+
108+ // Setup event handler to capture it
109+ envVarManager
110+ . setup ( ( m ) => m . onDidChangeEnvironmentVariables )
111+ . returns ( ( handler ) => {
112+ envVarChangeHandler = handler ;
113+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
114+ return { dispose : ( ) => { } } as any ;
115+ } ) ;
116+
94117 const mockConfig = {
95118 get : sinon . stub ( ) ,
96119 } ;
@@ -109,9 +132,9 @@ suite('TerminalEnvVarInjector Notification Tests', () => {
109132 await new Promise ( ( resolve ) => setTimeout ( resolve , 10 ) ) ; // Allow async notification
110133
111134 // Assert - notification should be shown
112- assert ( mockShowInformationMessage . called , 'showInformationMessage should be called' ) ;
135+ assert . ok ( mockShowInformationMessage . called , 'showInformationMessage should be called' ) ;
113136 const notificationCall = mockShowInformationMessage . getCall ( 0 ) ;
114- assert (
137+ assert . ok (
115138 notificationCall . args [ 0 ] . includes ( 'environment file is configured' ) ,
116139 'Notification should mention environment file' ,
117140 ) ;
@@ -126,6 +149,16 @@ suite('TerminalEnvVarInjector Notification Tests', () => {
126149 // Arrange - user has previously dismissed the notification
127150 mockState . get . resolves ( true ) ;
128151
152+ // Setup environment variable change handler to capture it
153+ envVarManager . reset ( ) ;
154+ envVarManager
155+ . setup ( ( m ) => m . onDidChangeEnvironmentVariables )
156+ . returns ( ( handler ) => {
157+ envVarChangeHandler = handler ;
158+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
159+ return { dispose : ( ) => { } } as any ;
160+ } ) ;
161+
129162 const mockConfig = {
130163 get : sinon . stub ( ) ,
131164 } ;
@@ -144,14 +177,24 @@ suite('TerminalEnvVarInjector Notification Tests', () => {
144177 await new Promise ( ( resolve ) => setTimeout ( resolve , 10 ) ) ; // Allow async notification
145178
146179 // Assert - notification should NOT be shown
147- assert ( ! mockShowInformationMessage . called , 'showInformationMessage should not be called' ) ;
180+ assert . ok ( ! mockShowInformationMessage . called , 'showInformationMessage should not be called' ) ;
148181 } ) ;
149182
150183 test ( 'should store preference when user clicks "Don\'t Show Again"' , async ( ) => {
151184 // Arrange - user clicks the "Don't Show Again" button
152185 mockState . get . resolves ( false ) ;
153186 mockShowInformationMessage . resolves ( Common . dontShowAgain ) ;
154187
188+ // Setup environment variable change handler to capture it
189+ envVarManager . reset ( ) ;
190+ envVarManager
191+ . setup ( ( m ) => m . onDidChangeEnvironmentVariables )
192+ . returns ( ( handler ) => {
193+ envVarChangeHandler = handler ;
194+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
195+ return { dispose : ( ) => { } } as any ;
196+ } ) ;
197+
155198 const mockConfig = {
156199 get : sinon . stub ( ) ,
157200 } ;
@@ -170,7 +213,7 @@ suite('TerminalEnvVarInjector Notification Tests', () => {
170213 await new Promise ( ( resolve ) => setTimeout ( resolve , 50 ) ) ; // Allow async notification and state update
171214
172215 // Assert - state should be set to true
173- assert ( mockState . set . called , 'state.set should be called' ) ;
216+ assert . ok ( mockState . set . called , 'state.set should be called' ) ;
174217 const setCall = mockState . set . getCall ( 0 ) ;
175218 assert . strictEqual ( setCall . args [ 0 ] , 'dontShowEnvFileNotification' , 'Should use correct state key' ) ;
176219 assert . strictEqual ( setCall . args [ 1 ] , true , 'Should set state to true' ) ;
@@ -180,6 +223,16 @@ suite('TerminalEnvVarInjector Notification Tests', () => {
180223 // Arrange - useEnvFile is enabled
181224 mockState . get . resolves ( false ) ;
182225
226+ // Setup environment variable change handler to capture it
227+ envVarManager . reset ( ) ;
228+ envVarManager
229+ . setup ( ( m ) => m . onDidChangeEnvironmentVariables )
230+ . returns ( ( handler ) => {
231+ envVarChangeHandler = handler ;
232+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
233+ return { dispose : ( ) => { } } as any ;
234+ } ) ;
235+
183236 const mockConfig = {
184237 get : sinon . stub ( ) ,
185238 } ;
@@ -198,13 +251,23 @@ suite('TerminalEnvVarInjector Notification Tests', () => {
198251 await new Promise ( ( resolve ) => setTimeout ( resolve , 10 ) ) ; // Allow async notification
199252
200253 // Assert - notification should NOT be shown
201- assert ( ! mockShowInformationMessage . called , 'showInformationMessage should not be called' ) ;
254+ assert . ok ( ! mockShowInformationMessage . called , 'showInformationMessage should not be called' ) ;
202255 } ) ;
203256
204257 test ( 'should not show notification when envFile is not configured' , async ( ) => {
205258 // Arrange - no envFile configured
206259 mockState . get . resolves ( false ) ;
207260
261+ // Setup environment variable change handler to capture it
262+ envVarManager . reset ( ) ;
263+ envVarManager
264+ . setup ( ( m ) => m . onDidChangeEnvironmentVariables )
265+ . returns ( ( handler ) => {
266+ envVarChangeHandler = handler ;
267+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
268+ return { dispose : ( ) => { } } as any ;
269+ } ) ;
270+
208271 const mockConfig = {
209272 get : sinon . stub ( ) ,
210273 } ;
@@ -223,6 +286,6 @@ suite('TerminalEnvVarInjector Notification Tests', () => {
223286 await new Promise ( ( resolve ) => setTimeout ( resolve , 10 ) ) ; // Allow async notification
224287
225288 // Assert - notification should NOT be shown
226- assert ( ! mockShowInformationMessage . called , 'showInformationMessage should not be called' ) ;
289+ assert . ok ( ! mockShowInformationMessage . called , 'showInformationMessage should not be called' ) ;
227290 } ) ;
228291} ) ;
0 commit comments