mirror of
https://github.com/Adembc/lazyssh.git
synced 2026-07-14 12:13:34 +02:00
feat: Add 60+ SSH config field support with enhanced UI (#50)
This commit is contained in:
@@ -0,0 +1,173 @@
|
||||
// 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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user