Files
ssh-netbox-wrapper/internal/ssh/args_test.go
T
Sebastian Unterschütz 7c902cab3a
Release / release (push) Successful in 50s
feat: introduce shortcuts and shell hook support
- **Shortcuts**: Add hostname normalization with domain stripping and hyphen folding. Include alias generation for cached hosts.
- **Shell Hook**: Automate 24h cache refresh trigger with shell startup hook. Add install/uninstall commands for bash, zsh, and fish.
- **Wizard**: Extend setup wizard to configure shortcuts (domains, hyphen stripping) and default SSH port.
- **Cache**: Add `GetByShortcut` for resolving hosts via normalized shortcuts. Implement `NeedsRefresh` / `SetRefreshed` logic for refresh timestamps.
- **Tests**: Comprehensive unit tests for shortcuts, hook installation, cache refresh, and alias generation.
- **Docs**: Update README with shortcuts, shell hook, and default SSH port configuration.
2026-05-27 22:53:24 +02:00

193 lines
4.9 KiB
Go

package ssh
import (
"testing"
)
func TestParse_BareHostname(t *testing.T) {
got := Parse([]string{"myhost"})
assertParsed(t, got, "myhost", "", 0)
}
func TestParse_UserAtHost(t *testing.T) {
got := Parse([]string{"admin@myhost"})
assertParsed(t, got, "myhost", "admin", 0)
}
func TestParse_PortFlag_Separated(t *testing.T) {
got := Parse([]string{"-p", "2222", "myhost"})
assertParsed(t, got, "myhost", "", 2)
}
func TestParse_PortFlag_Attached(t *testing.T) {
got := Parse([]string{"-p2222", "myhost"})
assertParsed(t, got, "myhost", "", 1)
}
func TestParse_IdentityFlag(t *testing.T) {
got := Parse([]string{"-i", "/path/to/key", "user@myhost", "ls"})
assertParsed(t, got, "myhost", "user", 2)
}
func TestParse_VerboseFlag(t *testing.T) {
got := Parse([]string{"-v", "myhost"})
assertParsed(t, got, "myhost", "", 1)
}
func TestParse_OptionFlag(t *testing.T) {
got := Parse([]string{"-o", "StrictHostKeyChecking=no", "myhost"})
assertParsed(t, got, "myhost", "", 2)
}
func TestParse_JumpHost(t *testing.T) {
got := Parse([]string{"-J", "jumphost", "-p", "22", "target"})
assertParsed(t, got, "target", "", 4)
}
func TestParse_MultipleFlags(t *testing.T) {
got := Parse([]string{"-v", "-p", "22", "-i", "key", "root@host", "uptime"})
assertParsed(t, got, "host", "root", 5)
}
func TestParse_DoubleDash(t *testing.T) {
got := Parse([]string{"--", "myhost"})
assertParsed(t, got, "myhost", "", 1)
}
func TestParse_DoubleDash_WithFlags(t *testing.T) {
// flags after -- should be treated as destination
got := Parse([]string{"-v", "--", "-not-a-flag"})
assertParsed(t, got, "-not-a-flag", "", 2)
}
func TestParse_NoDestination(t *testing.T) {
got := Parse([]string{"-v", "-p", "2222"})
if got != nil {
t.Errorf("expected nil for args without destination, got %+v", got)
}
}
func TestParse_EmptyArgs(t *testing.T) {
got := Parse([]string{})
if got != nil {
t.Error("empty args should return nil")
}
}
func TestParse_OnlyDoubleDash(t *testing.T) {
got := Parse([]string{"--"})
if got != nil {
t.Error("only -- with no destination should return nil")
}
}
func TestReplaceHost_PlainHost(t *testing.T) {
args := []string{"myhost"}
result := ReplaceHost(args, 0, "10.0.0.1")
if result[0] != "10.0.0.1" {
t.Errorf("got %q, want %q", result[0], "10.0.0.1")
}
}
func TestReplaceHost_PreservesUserPrefix(t *testing.T) {
args := []string{"-p", "22", "admin@myhost", "ls"}
result := ReplaceHost(args, 2, "10.0.0.1")
if result[2] != "admin@10.0.0.1" {
t.Errorf("got %q, want %q", result[2], "admin@10.0.0.1")
}
}
func TestReplaceHost_DoesNotMutateOriginal(t *testing.T) {
args := []string{"myhost"}
_ = ReplaceHost(args, 0, "10.0.0.1")
if args[0] != "myhost" {
t.Error("ReplaceHost must not mutate the original slice")
}
}
func TestReplaceHost_OtherArgsUnchanged(t *testing.T) {
args := []string{"-p", "22", "myhost"}
result := ReplaceHost(args, 2, "10.0.0.1")
if result[0] != "-p" || result[1] != "22" {
t.Errorf("other args should be unchanged: %v", result)
}
}
func TestHasUserFlag_FlagSeparated(t *testing.T) {
if !HasUserFlag([]string{"-l", "admin", "host"}) {
t.Error("should detect -l <user>")
}
}
func TestHasUserFlag_FlagAttached(t *testing.T) {
if !HasUserFlag([]string{"-ladmin", "host"}) {
t.Error("should detect -l<user> (attached form)")
}
}
func TestHasUserFlag_NotPresent(t *testing.T) {
if HasUserFlag([]string{"-p", "22", "host"}) {
t.Error("should not detect user flag when absent")
}
}
func TestHasUserFlag_EmptyArgs(t *testing.T) {
if HasUserFlag([]string{}) {
t.Error("empty args should return false")
}
}
func TestHasUserFlag_LFlagAtEnd(t *testing.T) {
// -l at the very end with no value — should not panic
if HasUserFlag([]string{"-l"}) {
t.Error("-l with no value should return false")
}
}
func TestHasPortFlag_FlagSeparated(t *testing.T) {
if !HasPortFlag([]string{"-p", "2222", "host"}) {
t.Error("should detect -p <port>")
}
}
func TestHasPortFlag_FlagAttached(t *testing.T) {
if !HasPortFlag([]string{"-p2222", "host"}) {
t.Error("should detect -p<port> (attached form)")
}
}
func TestHasPortFlag_NotPresent(t *testing.T) {
if HasPortFlag([]string{"-l", "admin", "host"}) {
t.Error("should not detect port flag when absent")
}
}
func TestHasPortFlag_EmptyArgs(t *testing.T) {
if HasPortFlag([]string{}) {
t.Error("empty args should return false")
}
}
func TestHasPortFlag_PAtEnd(t *testing.T) {
// -p at the very end with no value — should return false
if HasPortFlag([]string{"-p"}) {
t.Error("-p with no value should return false")
}
}
func assertParsed(t *testing.T, got *ParsedArgs, host, user string, destIdx int) {
t.Helper()
if got == nil {
t.Fatal("Parse returned nil")
}
if got.Host != host {
t.Errorf("host: got %q, want %q", got.Host, host)
}
if got.User != user {
t.Errorf("user: got %q, want %q", got.User, user)
}
if got.DestIdx != destIdx {
t.Errorf("destIdx: got %d, want %d", got.DestIdx, destIdx)
}
}