@@ -84,6 +84,7 @@ const mockTelemetryServiceInstance = {
8484vi . mock ( "@roo-code/telemetry" , ( ) => ( {
8585 TelemetryService : {
8686 createInstance : vi . fn ( ) . mockReturnValue ( mockTelemetryServiceInstance ) ,
87+ hasInstance : vi . fn ( ) . mockReturnValue ( true ) ,
8788 get instance ( ) {
8889 return mockTelemetryServiceInstance
8990 } ,
@@ -461,5 +462,32 @@ describe("extension.ts", () => {
461462
462463 setTerminalProfileSpy . mockRestore ( )
463464 } )
465+
466+ // Review finding: every other TelemetryService call site touched by this PR checks
467+ // hasInstance() first; deactivate()'s shutdown call didn't. Not a crash today (the mock
468+ // always resolves), but TelemetryService.instance throws for real if no instance exists,
469+ // so the guard keeps this call site consistent with the rest of the file.
470+ test ( "does not touch TelemetryService.instance when no instance exists" , async ( ) => {
471+ const { TelemetryService } = await import ( "@roo-code/telemetry" )
472+ const { Terminal } = await import ( "../integrations/terminal/Terminal" )
473+ const { TerminalRegistry } = await import ( "../integrations/terminal/TerminalRegistry" )
474+
475+ const setTerminalProfileSpy = vi . spyOn ( Terminal , "setTerminalProfile" )
476+
477+ const { activate, deactivate } = await import ( "../extension" )
478+ await activate ( mockContext )
479+
480+ // Flip to false only after activate() completes, so this only exercises
481+ // deactivate()'s own guard rather than any hasInstance() check during activation.
482+ vi . mocked ( TelemetryService . hasInstance ) . mockReturnValue ( false )
483+
484+ await expect ( deactivate ( ) ) . resolves . toBeUndefined ( )
485+
486+ expect ( TelemetryService . instance . shutdown ) . not . toHaveBeenCalled ( )
487+ expect ( setTerminalProfileSpy ) . toHaveBeenCalledWith ( undefined )
488+ expect ( TerminalRegistry . cleanup ) . toHaveBeenCalledTimes ( 1 )
489+
490+ setTerminalProfileSpy . mockRestore ( )
491+ } )
464492 } )
465493} )
0 commit comments