@@ -19,7 +19,17 @@ vi.mock("vscode", () => ({
1919 window : {
2020 showInformationMessage : vi . fn ( ) ,
2121 showErrorMessage : vi . fn ( ) ,
22+ createTerminal : vi . fn ( ) ,
2223 } ,
24+ EventEmitter : vi . fn ( ) . mockImplementation ( ( ) => ( {
25+ event : vi . fn ( ) ,
26+ fire : vi . fn ( ) ,
27+ dispose : vi . fn ( ) ,
28+ } ) ) ,
29+ TerminalLocation : {
30+ Panel : 1 ,
31+ } ,
32+ ThemeIcon : vi . fn ( ) ,
2333} ) )
2434
2535vi . mock ( "fs/promises" , ( ) => ( {
@@ -62,6 +72,15 @@ vi.mock("./featureSet", () => ({
6272
6373vi . mock ( "./util" , ( ) => ( {
6474 parseRemoteAuthority : vi . fn ( ) ,
75+ findPort : vi . fn ( ) ,
76+ } ) )
77+
78+ vi . mock ( "find-process" , ( ) => ( {
79+ default : vi . fn ( ) ,
80+ } ) )
81+
82+ vi . mock ( "pretty-bytes" , ( ) => ( {
83+ default : vi . fn ( ( bytes ) => `${ bytes } B` ) ,
6584} ) )
6685
6786// Create a testable Remote class that exposes protected methods
@@ -85,6 +104,18 @@ class TestableRemote extends Remote {
85104 public fetchWorkspace ( workspaceRestClient : Api , parts : any , baseUrlRaw : string , remoteAuthority : string ) {
86105 return super . fetchWorkspace ( workspaceRestClient , parts , baseUrlRaw , remoteAuthority )
87106 }
107+
108+ public createBuildLogTerminal ( writeEmitter : vscode . EventEmitter < string > ) {
109+ return super . createBuildLogTerminal ( writeEmitter )
110+ }
111+
112+ public searchSSHLogForPID ( logPath : string ) {
113+ return super . searchSSHLogForPID ( logPath )
114+ }
115+
116+ public updateNetworkStatus ( networkStatus : vscode . StatusBarItem , network : any ) {
117+ return super . updateNetworkStatus ( networkStatus , network )
118+ }
88119}
89120
90121describe ( "Remote" , ( ) => {
@@ -478,4 +509,106 @@ describe("Remote", () => {
478509 )
479510 } )
480511 } )
512+
513+ describe ( "createBuildLogTerminal" , ( ) => {
514+ it ( "should create terminal with correct configuration" , ( ) => {
515+ const mockWriteEmitter = new vscode . EventEmitter < string > ( )
516+ mockWriteEmitter . event = vi . fn ( )
517+
518+ const mockTerminal = { name : "Build Log" }
519+ vscode . window . createTerminal . mockReturnValue ( mockTerminal )
520+
521+ const result = remote . createBuildLogTerminal ( mockWriteEmitter )
522+
523+ expect ( result ) . toBe ( mockTerminal )
524+ expect ( vscode . window . createTerminal ) . toHaveBeenCalledWith ( {
525+ name : "Build Log" ,
526+ location : vscode . TerminalLocation . Panel ,
527+ iconPath : expect . any ( vscode . ThemeIcon ) ,
528+ pty : expect . objectContaining ( {
529+ onDidWrite : mockWriteEmitter . event ,
530+ close : expect . any ( Function ) ,
531+ open : expect . any ( Function ) ,
532+ } ) ,
533+ } )
534+ } )
535+ } )
536+
537+ describe ( "searchSSHLogForPID" , ( ) => {
538+ it ( "should find SSH process ID from log file" , async ( ) => {
539+ const logPath = "/path/to/ssh.log"
540+
541+ const fs = await import ( "fs/promises" )
542+ vi . mocked ( fs . readFile ) . mockResolvedValue ( "Forwarding port 12345..." )
543+
544+ const { findPort } = await import ( "./util" )
545+ vi . mocked ( findPort ) . mockResolvedValue ( 12345 )
546+
547+ const find = ( await import ( "find-process" ) ) . default
548+ vi . mocked ( find ) . mockResolvedValue ( [ { pid : 54321 , name : "ssh" } ] )
549+
550+ const result = await remote . searchSSHLogForPID ( logPath )
551+
552+ expect ( result ) . toBe ( 54321 )
553+ expect ( fs . readFile ) . toHaveBeenCalledWith ( logPath , "utf8" )
554+ expect ( findPort ) . toHaveBeenCalled ( )
555+ expect ( find ) . toHaveBeenCalledWith ( "port" , 12345 )
556+ } )
557+
558+ it ( "should return undefined when no port found" , async ( ) => {
559+ const logPath = "/path/to/ssh.log"
560+
561+ const fs = await import ( "fs/promises" )
562+ vi . mocked ( fs . readFile ) . mockResolvedValue ( "No port info here" )
563+
564+ const { findPort } = await import ( "./util" )
565+ vi . mocked ( findPort ) . mockResolvedValue ( undefined )
566+
567+ const result = await remote . searchSSHLogForPID ( logPath )
568+
569+ expect ( result ) . toBeUndefined ( )
570+ } )
571+ } )
572+
573+ describe ( "updateNetworkStatus" , ( ) => {
574+ let mockStatusBar : any
575+
576+ beforeEach ( ( ) => {
577+ mockStatusBar = {
578+ text : "" ,
579+ tooltip : "" ,
580+ show : vi . fn ( ) ,
581+ hide : vi . fn ( ) ,
582+ dispose : vi . fn ( ) ,
583+ }
584+ } )
585+
586+ it ( "should update status for peer-to-peer connection" , ( ) => {
587+ const network = {
588+ using_coder_connect : false ,
589+ p2p : true ,
590+ latency : 15.5 ,
591+ download_bytes_sec : 1000000 ,
592+ upload_bytes_sec : 500000 ,
593+ }
594+
595+ remote . updateNetworkStatus ( mockStatusBar , network )
596+
597+ expect ( mockStatusBar . text ) . toBe ( "$(globe) Direct (15.50ms)" )
598+ expect ( mockStatusBar . tooltip ) . toContain ( "You're connected peer-to-peer" )
599+ expect ( mockStatusBar . show ) . toHaveBeenCalled ( )
600+ } )
601+
602+ it ( "should update status for Coder Connect" , ( ) => {
603+ const network = {
604+ using_coder_connect : true ,
605+ }
606+
607+ remote . updateNetworkStatus ( mockStatusBar , network )
608+
609+ expect ( mockStatusBar . text ) . toBe ( "$(globe) Coder Connect " )
610+ expect ( mockStatusBar . tooltip ) . toBe ( "You're connected using Coder Connect." )
611+ expect ( mockStatusBar . show ) . toHaveBeenCalled ( )
612+ } )
613+ } )
481614} )
0 commit comments