@@ -77,6 +77,27 @@ func TestShellMetadataHelpers(t *testing.T) {
7777 }
7878}
7979
80+ func TestWindowsAdminUsernameDetection (t * testing.T ) {
81+ cases := []struct {
82+ name string
83+ currentUser string
84+ envUser string
85+ want bool
86+ }{
87+ {name : "plain administrator" , currentUser : "Administrator" , want : true },
88+ {name : "domain administrator" , currentUser : `WINBOX\\Administrator` , want : true },
89+ {name : "env administrator fallback" , envUser : "Administrator" , want : true },
90+ {name : "normal user" , currentUser : `WINBOX\\bagas` , envUser : "bagas" , want : false },
91+ }
92+ for _ , tt := range cases {
93+ t .Run (tt .name , func (t * testing.T ) {
94+ if got := isWindowsAdministrator (tt .currentUser , tt .envUser ); got != tt .want {
95+ t .Fatalf ("isWindowsAdministrator() = %v, want %v" , got , tt .want )
96+ }
97+ })
98+ }
99+ }
100+
80101func TestOneShotArgs (t * testing.T ) {
81102 name , args := oneShotArgs ("echo ok" )
82103 if runtime .GOOS == "windows" {
@@ -108,6 +129,22 @@ func TestRunOneShotMergesStdoutStderrAndExitCode(t *testing.T) {
108129 }
109130}
110131
132+ func TestFileTransferHelpers (t * testing.T ) {
133+ path := t .TempDir () + "/hello.txt"
134+ ok , bytesWritten , errMsg := writeFileB64 (path , "aGVsbG8=" )
135+ if ! ok || bytesWritten != 5 || errMsg != "" {
136+ t .Fatalf ("writeFileB64() = %v, %d, %q" , ok , bytesWritten , errMsg )
137+ }
138+
139+ result := readFileB64 (path )
140+ if result ["ok" ] != true || result ["content_b64" ] != "aGVsbG8=" || result ["bytes" ] != 5 {
141+ t .Fatalf ("unexpected readFileB64 result: %+v" , result )
142+ }
143+ if result ["filename" ] != "hello.txt" {
144+ t .Fatalf ("unexpected filename: %+v" , result ["filename" ])
145+ }
146+ }
147+
111148func TestReadCommandsExecutesCommandAndSendsResult (t * testing.T ) {
112149 client , server := websocketPair (t )
113150 defer server .Close ()
@@ -158,6 +195,67 @@ func TestReadCommandsExecutesCommandAndSendsResult(t *testing.T) {
158195 }
159196}
160197
198+ func TestReadCommandsHandlesFileTransferMessages (t * testing.T ) {
199+ client , server := websocketPair (t )
200+ defer server .Close ()
201+
202+ done := make (chan struct {})
203+ go func () {
204+ readCommands (& wsConn {conn : client }, "" )
205+ close (done )
206+ }()
207+
208+ path := t .TempDir () + "/ws-file.txt"
209+ if err := server .WriteJSON (map [string ]any {
210+ "type" : "file_write" ,
211+ "id" : "write-1" ,
212+ "path" : path ,
213+ "content_b64" : "aGVsbG8=" ,
214+ }); err != nil {
215+ t .Fatalf ("write file_write: %v" , err )
216+ }
217+ var writeResult struct {
218+ Type string `json:"type"`
219+ ID string `json:"id"`
220+ OK bool `json:"ok"`
221+ Bytes int `json:"bytes"`
222+ }
223+ if err := server .ReadJSON (& writeResult ); err != nil {
224+ t .Fatalf ("read file_write result: %v" , err )
225+ }
226+ if writeResult .Type != "file_write_result" || writeResult .ID != "write-1" || ! writeResult .OK || writeResult .Bytes != 5 {
227+ t .Fatalf ("unexpected file_write result: %+v" , writeResult )
228+ }
229+
230+ if err := server .WriteJSON (map [string ]any {
231+ "type" : "file_read" ,
232+ "id" : "read-1" ,
233+ "path" : path ,
234+ }); err != nil {
235+ t .Fatalf ("write file_read: %v" , err )
236+ }
237+ var readResult struct {
238+ Type string `json:"type"`
239+ ID string `json:"id"`
240+ OK bool `json:"ok"`
241+ ContentB64 string `json:"content_b64"`
242+ Bytes int `json:"bytes"`
243+ }
244+ if err := server .ReadJSON (& readResult ); err != nil {
245+ t .Fatalf ("read file_read result: %v" , err )
246+ }
247+ if readResult .Type != "file_read_result" || readResult .ID != "read-1" || ! readResult .OK || readResult .ContentB64 != "aGVsbG8=" || readResult .Bytes != 5 {
248+ t .Fatalf ("unexpected file_read result: %+v" , readResult )
249+ }
250+
251+ _ = server .WriteJSON (map [string ]any {"type" : "bye" })
252+ select {
253+ case <- done :
254+ case <- time .After (2 * time .Second ):
255+ t .Fatalf ("readCommands did not exit after bye" )
256+ }
257+ }
258+
161259func TestReadCommandsIgnoresMalformedMessages (t * testing.T ) {
162260 client , server := websocketPair (t )
163261 defer server .Close ()
0 commit comments