Files
HostKeeper/cmd/hostkeeper/add_test.go
T
Swana Diva Borneos 4087c5fdc7 feat: add & list commands with deadlock fix
- Add 'add' command: register hosts via flags or interactive prompts
  Supports password/key/both auth, groups, tags, notes, port override
- Add 'list' command: display hosts with filtering and formatting
  Supports --group, --tag filters, --sort, table/json/wide output
- Fix deadlock bug in JSON storage (RLock within Lock)
  Introduced internal list functions that don't lock
  Affects: ListHosts/GetHost/SaveHost/DeleteHost + KeyPair + Snippet
- Add comprehensive tests for add and list commands
- Update PROJECT_STATE.md (Tasks 1-8 complete, ~55% done)
2026-06-23 10:56:04 +07:00

106 lines
2.3 KiB
Go

package main
import (
"testing"
)
func TestAddCommandExists(t *testing.T) {
if addCmd == nil {
t.Fatal("addCmd should not be nil")
}
if addCmd.Use != "add [name]" {
t.Errorf("expected Use 'add [name]', got '%s'", addCmd.Use)
}
if addCmd.Short == "" {
t.Error("Short description should not be empty")
}
}
func TestAddCommandFlags(t *testing.T) {
expectedFlags := []string{"host", "port", "user", "password", "key", "auth-type", "group", "tags", "notes"}
for _, flagName := range expectedFlags {
if addCmd.Flags().Lookup(flagName) == nil {
t.Errorf("flag '%s' should be defined", flagName)
}
}
}
func TestAddCommandValidation(t *testing.T) {
tests := []struct {
name string
args []string
hostFlag string
userFlag string
passFlag string
wantError bool
errContains string
}{
{
name: "missing hostname",
args: []string{"myserver"},
userFlag: "admin",
passFlag: "pass",
wantError: true,
errContains: "hostname is required",
},
{
name: "missing username",
args: []string{"myserver"},
hostFlag: "192.168.1.10",
passFlag: "pass",
wantError: true,
errContains: "username is required",
},
{
name: "missing auth",
args: []string{"myserver"},
hostFlag: "192.168.1.10",
userFlag: "admin",
wantError: true,
errContains: "authentication is required",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Reset flags
addHostname = tt.hostFlag
addUser = tt.userFlag
addPassword = tt.passFlag
addPort = 0
addKeyPath = ""
addAuthType = ""
addGroup = ""
addTags = nil
addNotes = ""
// Set HOME to temp dir to avoid polluting real config
t.Setenv("HOME", "/tmp/hostkeeper-test-nonexistent")
err := runAddHost(addCmd, tt.args)
if tt.wantError && err == nil {
t.Errorf("expected error but got none")
}
if !tt.wantError && err != nil {
t.Errorf("unexpected error: %v", err)
}
if tt.errContains != "" && err != nil {
if !contains(err.Error(), tt.errContains) {
t.Errorf("error should contain '%s', got '%s'", tt.errContains, err.Error())
}
}
})
}
}
func contains(s, substr string) bool {
for i := 0; i <= len(s)-len(substr); i++ {
if s[i:i+len(substr)] == substr {
return true
}
}
return false
}