package config import "testing" func TestNormalizeHostPort(t *testing.T) { tests := []struct { name string host string defaultPort string want string }{ { name: "adds default port to https host", host: "https://example.com", defaultPort: defaultPVEPort, want: "https://example.com:8006", }, { name: "adds default port when scheme missing", host: "pbs.lan", defaultPort: defaultPBSPort, want: "https://pbs.lan:8007", }, { name: "preserves existing port and scheme", host: "http://example.com:8443", defaultPort: defaultPVEPort, want: "http://example.com:8443", }, { name: "drops path segments before applying port", host: "https://example.com/api", defaultPort: defaultPVEPort, want: "https://example.com:8006", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := normalizeHostPort(tt.host, tt.defaultPort); got != tt.want { t.Fatalf("normalizeHostPort(%q, %q) = %q, want %q", tt.host, tt.defaultPort, got, tt.want) } }) } } func TestCreateConfigHelpersNormalizeHosts(t *testing.T) { pveCfg := PVEInstance{ Host: "https://pve.local", User: "root@pam", } pveClientCfg := CreateProxmoxConfig(&pveCfg) if pveClientCfg.Host != "https://pve.local:8006" { t.Fatalf("expected default port on PVE host, got %q", pveClientCfg.Host) } pbsCfg := PBSInstance{ Host: "pbs.local", User: "root@pam", } pbsClientCfg := CreatePBSConfig(&pbsCfg) if pbsClientCfg.Host != "https://pbs.local:8007" { t.Fatalf("expected default PBS port on host, got %q", pbsClientCfg.Host) } pmgCfg := PMGInstance{ Host: "https://pmg.local/api", User: "root@pam", } pmgClientCfg := CreatePMGConfig(&pmgCfg) if pmgClientCfg.Host != "https://pmg.local:8006" { t.Fatalf("expected default PMG port on host, got %q", pmgClientCfg.Host) } fromFields := CreateProxmoxConfigFromFields("https://cluster.local", "root@pam", "", "token!name", "value", "", true) if fromFields.Host != "https://cluster.local:8006" { t.Fatalf("expected default port on host built from fields, got %q", fromFields.Host) } } func TestCreateProxmoxConfigFromFields(t *testing.T) { t.Parallel() tests := []struct { name string host string user string password string tokenName string tokenValue string fingerprint string verifySSL bool expectedUser string expectedHost string }{ { name: "user without realm gets @pam appended (password auth)", host: "https://pve.local", user: "root", password: "secret", tokenName: "", tokenValue: "", expectedUser: "root@pam", expectedHost: "https://pve.local:8006", }, { name: "user with realm unchanged", host: "https://pve.local", user: "admin@pve", password: "secret", tokenName: "", tokenValue: "", expectedUser: "admin@pve", expectedHost: "https://pve.local:8006", }, { name: "token auth does not modify user", host: "https://pve.local", user: "root", password: "", tokenName: "mytoken", tokenValue: "token-value", expectedUser: "root", expectedHost: "https://pve.local:8006", }, { name: "empty user unchanged", host: "https://pve.local", user: "", password: "secret", tokenName: "", tokenValue: "", expectedUser: "", expectedHost: "https://pve.local:8006", }, { name: "fingerprint and verifySSL preserved", host: "pve.local", user: "root", password: "secret", tokenName: "", tokenValue: "", fingerprint: "AA:BB:CC", verifySSL: false, expectedUser: "root@pam", expectedHost: "https://pve.local:8006", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { t.Parallel() cfg := CreateProxmoxConfigFromFields(tt.host, tt.user, tt.password, tt.tokenName, tt.tokenValue, tt.fingerprint, tt.verifySSL) if cfg.User != tt.expectedUser { t.Errorf("User = %q, want %q", cfg.User, tt.expectedUser) } if cfg.Host != tt.expectedHost { t.Errorf("Host = %q, want %q", cfg.Host, tt.expectedHost) } if cfg.Password != tt.password { t.Errorf("Password = %q, want %q", cfg.Password, tt.password) } if cfg.TokenName != tt.tokenName { t.Errorf("TokenName = %q, want %q", cfg.TokenName, tt.tokenName) } if cfg.TokenValue != tt.tokenValue { t.Errorf("TokenValue = %q, want %q", cfg.TokenValue, tt.tokenValue) } if cfg.Fingerprint != tt.fingerprint { t.Errorf("Fingerprint = %q, want %q", cfg.Fingerprint, tt.fingerprint) } if cfg.VerifySSL != tt.verifySSL { t.Errorf("VerifySSL = %v, want %v", cfg.VerifySSL, tt.verifySSL) } }) } } func TestStripDefaultPort(t *testing.T) { tests := []struct { name string host string defaultPort string want string }{ { name: "removes default PVE port", host: "https://pve.local:8006", defaultPort: defaultPVEPort, want: "https://pve.local", }, { name: "keeps non-default port", host: "https://pve.local:8443", defaultPort: defaultPVEPort, want: "https://pve.local:8443", }, { name: "preserves http scheme when removing port", host: "http://pve.local:8006", defaultPort: defaultPVEPort, want: "http://pve.local", }, { name: "returns trimmed host unchanged when parse fails", host: "://bad", defaultPort: defaultPVEPort, want: "://bad", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := StripDefaultPort(tt.host, tt.defaultPort); got != tt.want { t.Fatalf("StripDefaultPort(%q, %q) = %q, want %q", tt.host, tt.defaultPort, got, tt.want) } }) } } func TestCreateProxmoxConfigWithHost(t *testing.T) { node := &PVEInstance{ User: "root@pam", Password: "secret", TokenName: "token", TokenValue: "value", VerifySSL: true, Fingerprint: "fingerprint", } // Test with normalizeHost = true cfg1 := CreateProxmoxConfigWithHost(node, "https://pve.local", true) if cfg1.Host != "https://pve.local:8006" { t.Errorf("Expected normalized host, got %s", cfg1.Host) } // Test with normalizeHost = false cfg2 := CreateProxmoxConfigWithHost(node, "https://pve.local", false) if cfg2.Host != "https://pve.local" { // Verbatim t.Errorf("Expected verbatim host, got %s", cfg2.Host) } } func TestCreatePMGConfigFromFields(t *testing.T) { cfg := CreatePMGConfigFromFields("pmg.local", "root@pam", "secret", "token", "value", "fingerprint", true) if cfg.Host != "https://pmg.local:8006" { t.Errorf("Expected normalized host, got %s", cfg.Host) } if cfg.User != "root@pam" { t.Errorf("Expected user root@pam, got %s", cfg.User) } }