// Copyright 2025. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package ui import ( "strings" "testing" "github.com/Adembc/lazyssh/internal/core/domain" ) func TestBuildSSHCommand_PortForwarding(t *testing.T) { tests := []struct { name string server domain.Server expected []string // expected parts in the command }{ { name: "local forward", server: domain.Server{ Alias: "test", Host: "example.com", User: "user", LocalForward: []string{"8080:localhost:80", "3306:db.internal:3306"}, }, expected: []string{"ssh", "-L", "8080:localhost:80", "-L", "3306:db.internal:3306", "user@example.com"}, }, { name: "remote forward", server: domain.Server{ Alias: "test", Host: "example.com", User: "user", RemoteForward: []string{"8080:localhost:3000", "*:80:localhost:8080"}, }, expected: []string{"ssh", "-R", "8080:localhost:3000", "-R", "*:80:localhost:8080", "user@example.com"}, }, { name: "dynamic forward", server: domain.Server{ Alias: "test", Host: "example.com", User: "user", DynamicForward: []string{"1080", "localhost:1081"}, }, expected: []string{"ssh", "-D", "1080", "-D", "localhost:1081", "user@example.com"}, }, { name: "all forward types", server: domain.Server{ Alias: "test", Host: "example.com", User: "user", LocalForward: []string{"8080:localhost:80"}, RemoteForward: []string{"9090:localhost:9090"}, DynamicForward: []string{"1080"}, }, expected: []string{"ssh", "-L", "8080:localhost:80", "-R", "9090:localhost:9090", "-D", "1080", "user@example.com"}, }, { name: "forward with bind address", server: domain.Server{ Alias: "test", Host: "example.com", User: "user", LocalForward: []string{"127.0.0.1:8080:localhost:80", "*:3000:localhost:3000"}, }, expected: []string{"ssh", "-L", "127.0.0.1:8080:localhost:80", "-L", "*:3000:localhost:3000", "user@example.com"}, }, { name: "forward with additional options", server: domain.Server{ Alias: "test", Host: "example.com", User: "user", LocalForward: []string{"8080:localhost:80"}, ExitOnForwardFailure: "yes", GatewayPorts: "clientspecified", }, expected: []string{"ssh", "-L", "8080:localhost:80", "-o", "ExitOnForwardFailure=yes", "-o", "GatewayPorts=clientspecified", "user@example.com"}, }, { name: "clear all forwardings", server: domain.Server{ Alias: "test", Host: "example.com", User: "user", LocalForward: []string{"8080:localhost:80"}, ClearAllForwardings: "yes", }, expected: []string{"ssh", "-L", "8080:localhost:80", "-o", "ClearAllForwardings=yes", "user@example.com"}, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { result := BuildSSHCommand(tt.server) // Check that all expected parts are in the result for _, part := range tt.expected { if !strings.Contains(result, part) { t.Errorf("BuildSSHCommand() missing expected part %q in result: %q", part, result) } } // Additional check: ensure the command starts with "ssh" if !strings.HasPrefix(result, "ssh ") { t.Errorf("BuildSSHCommand() should start with 'ssh ', got: %q", result) } }) } } func TestBuildSSHCommand_CompleteCommand(t *testing.T) { server := domain.Server{ Alias: "myserver", Host: "example.com", User: "admin", Port: 2222, LocalForward: []string{"8080:localhost:80", "3306:db.internal:3306"}, RemoteForward: []string{"9090:localhost:9090"}, DynamicForward: []string{"1080"}, IdentityFiles: []string{"~/.ssh/id_rsa"}, } result := BuildSSHCommand(server) // Check command structure if !strings.HasPrefix(result, "ssh ") { t.Errorf("Command should start with 'ssh ', got: %q", result) } // Check port if !strings.Contains(result, "-p 2222") { t.Errorf("Command should contain port flag '-p 2222', got: %q", result) } // Check identity file if !strings.Contains(result, "-i ~/.ssh/id_rsa") { t.Errorf("Command should contain identity file flag, got: %q", result) } // Check all forwards expectedForwards := []string{ "-L 8080:localhost:80", "-L 3306:db.internal:3306", "-R 9090:localhost:9090", "-D 1080", } for _, forward := range expectedForwards { if !strings.Contains(result, forward) { t.Errorf("Command should contain forward %q, got: %q", forward, result) } } // Check user@host if !strings.Contains(result, "admin@example.com") { t.Errorf("Command should contain 'admin@example.com', got: %q", result) } }