test: Add tests for config handler utility functions

- TestSanitizeErrorMessage: All operation types and error hiding
- TestFindExistingGuestURL: Node matching and edge cases
- TestMatchInstanceNameByHost: Host normalization and matching
Coverage: api 27.7% → 28.0%
This commit is contained in:
rcourtman
2025-12-01 14:09:35 +00:00
parent a49526561b
commit b311625328
2 changed files with 336 additions and 0 deletions

View File

@@ -1,8 +1,11 @@
package api
import (
"errors"
"strings"
"testing"
"github.com/rcourtman/pulse-go-rewrite/internal/config"
)
func TestSanitizeInstallerURL(t *testing.T) {
@@ -330,3 +333,175 @@ func TestSanitizeSetupAuthToken(t *testing.T) {
})
}
}
func TestSanitizeErrorMessage(t *testing.T) {
t.Parallel()
tests := []struct {
name string
err error
operation string
expected string
}{
{
name: "create_client operation",
err: errors.New("connection refused"),
operation: "create_client",
expected: "Failed to initialize connection",
},
{
name: "connection operation",
err: errors.New("network unreachable"),
operation: "connection",
expected: "Connection failed. Please check your credentials and network settings",
},
{
name: "validation operation",
err: errors.New("invalid field"),
operation: "validation",
expected: "Invalid configuration",
},
{
name: "unknown operation",
err: errors.New("something went wrong"),
operation: "unknown_operation",
expected: "Operation failed",
},
{
name: "empty operation string",
err: errors.New("error"),
operation: "",
expected: "Operation failed",
},
{
name: "nil error still returns message",
err: nil,
operation: "create_client",
expected: "Failed to initialize connection",
},
{
name: "detailed error hidden from response",
err: errors.New("x509: certificate signed by unknown authority"),
operation: "connection",
expected: "Connection failed. Please check your credentials and network settings",
},
{
name: "sensitive error hidden from response",
err: errors.New("password: secret123"),
operation: "validation",
expected: "Invalid configuration",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
result := sanitizeErrorMessage(tt.err, tt.operation)
if result != tt.expected {
t.Errorf("sanitizeErrorMessage() = %q, want %q", result, tt.expected)
}
})
}
}
func TestFindExistingGuestURL(t *testing.T) {
t.Parallel()
tests := []struct {
name string
nodeName string
endpoints []config.ClusterEndpoint
expected string
}{
{
name: "empty endpoints",
nodeName: "node1",
endpoints: []config.ClusterEndpoint{},
expected: "",
},
{
name: "nil endpoints",
nodeName: "node1",
endpoints: nil,
expected: "",
},
{
name: "exact match",
nodeName: "pve1",
endpoints: []config.ClusterEndpoint{
{NodeName: "pve1", GuestURL: "https://pve1.local:8006"},
{NodeName: "pve2", GuestURL: "https://pve2.local:8006"},
},
expected: "https://pve1.local:8006",
},
{
name: "match second node",
nodeName: "pve2",
endpoints: []config.ClusterEndpoint{
{NodeName: "pve1", GuestURL: "https://pve1.local:8006"},
{NodeName: "pve2", GuestURL: "https://pve2.local:8006"},
},
expected: "https://pve2.local:8006",
},
{
name: "no match",
nodeName: "pve3",
endpoints: []config.ClusterEndpoint{
{NodeName: "pve1", GuestURL: "https://pve1.local:8006"},
{NodeName: "pve2", GuestURL: "https://pve2.local:8006"},
},
expected: "",
},
{
name: "empty node name",
nodeName: "",
endpoints: []config.ClusterEndpoint{
{NodeName: "pve1", GuestURL: "https://pve1.local:8006"},
},
expected: "",
},
{
name: "case sensitive match",
nodeName: "PVE1",
endpoints: []config.ClusterEndpoint{
{NodeName: "pve1", GuestURL: "https://pve1.local:8006"},
},
expected: "",
},
{
name: "returns first match when duplicates exist",
nodeName: "pve1",
endpoints: []config.ClusterEndpoint{
{NodeName: "pve1", GuestURL: "https://first.local:8006"},
{NodeName: "pve1", GuestURL: "https://second.local:8006"},
},
expected: "https://first.local:8006",
},
{
name: "empty GuestURL returned when matched",
nodeName: "pve1",
endpoints: []config.ClusterEndpoint{
{NodeName: "pve1", GuestURL: ""},
},
expected: "",
},
{
name: "single endpoint match",
nodeName: "pve1",
endpoints: []config.ClusterEndpoint{
{NodeName: "pve1", GuestURL: "https://pve1.local:8006"},
},
expected: "https://pve1.local:8006",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
result := findExistingGuestURL(tt.nodeName, tt.endpoints)
if result != tt.expected {
t.Errorf("findExistingGuestURL(%q, endpoints) = %q, want %q", tt.nodeName, result, tt.expected)
}
})
}
}

View File

@@ -5,6 +5,7 @@ import (
"time"
"github.com/rcourtman/pulse-go-rewrite/internal/alerts"
"github.com/rcourtman/pulse-go-rewrite/internal/config"
"github.com/rcourtman/pulse-go-rewrite/internal/models"
)
@@ -411,6 +412,166 @@ func TestFormatTimeMaybe(t *testing.T) {
}
}
func TestMatchInstanceNameByHost(t *testing.T) {
t.Parallel()
tests := []struct {
name string
cfg *config.Config
host string
expected string
}{
{
name: "nil config",
cfg: nil,
host: "example.com",
expected: "",
},
{
name: "empty host",
cfg: &config.Config{
PVEInstances: []config.PVEInstance{
{Name: "pve1", Host: "pve1.local"},
},
},
host: "",
expected: "",
},
{
name: "whitespace-only host",
cfg: &config.Config{
PVEInstances: []config.PVEInstance{
{Name: "pve1", Host: "pve1.local"},
},
},
host: " ",
expected: "",
},
{
name: "exact match",
cfg: &config.Config{
PVEInstances: []config.PVEInstance{
{Name: "pve1", Host: "pve1.local"},
{Name: "pve2", Host: "pve2.local"},
},
},
host: "pve1.local",
expected: "pve1",
},
{
name: "case insensitive match",
cfg: &config.Config{
PVEInstances: []config.PVEInstance{
{Name: "Production PVE", Host: "PVE.EXAMPLE.COM"},
},
},
host: "pve.example.com",
expected: "Production PVE",
},
{
name: "match with port in config",
cfg: &config.Config{
PVEInstances: []config.PVEInstance{
{Name: "pve1", Host: "pve1.local:8006"},
},
},
host: "pve1.local",
expected: "pve1",
},
{
name: "match with protocol in config",
cfg: &config.Config{
PVEInstances: []config.PVEInstance{
{Name: "pve1", Host: "https://pve1.local:8006"},
},
},
host: "pve1.local",
expected: "pve1",
},
{
name: "match with protocol in search host",
cfg: &config.Config{
PVEInstances: []config.PVEInstance{
{Name: "pve1", Host: "pve1.local"},
},
},
host: "https://pve1.local:8006",
expected: "pve1",
},
{
name: "no match",
cfg: &config.Config{
PVEInstances: []config.PVEInstance{
{Name: "pve1", Host: "pve1.local"},
{Name: "pve2", Host: "pve2.local"},
},
},
host: "pve3.local",
expected: "",
},
{
name: "empty instances",
cfg: &config.Config{
PVEInstances: []config.PVEInstance{},
},
host: "pve1.local",
expected: "",
},
{
name: "instance with empty host skipped",
cfg: &config.Config{
PVEInstances: []config.PVEInstance{
{Name: "empty", Host: ""},
{Name: "pve1", Host: "pve1.local"},
},
},
host: "pve1.local",
expected: "pve1",
},
{
name: "IP address match",
cfg: &config.Config{
PVEInstances: []config.PVEInstance{
{Name: "pve1", Host: "192.168.1.100"},
},
},
host: "192.168.1.100",
expected: "pve1",
},
{
name: "name has leading and trailing whitespace",
cfg: &config.Config{
PVEInstances: []config.PVEInstance{
{Name: " pve1 ", Host: "pve1.local"},
},
},
host: "pve1.local",
expected: "pve1",
},
{
name: "returns first match when duplicates exist",
cfg: &config.Config{
PVEInstances: []config.PVEInstance{
{Name: "first", Host: "pve.local"},
{Name: "second", Host: "pve.local"},
},
},
host: "pve.local",
expected: "first",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
result := matchInstanceNameByHost(tt.cfg, tt.host)
if result != tt.expected {
t.Errorf("matchInstanceNameByHost() = %q, want %q", result, tt.expected)
}
})
}
}
func TestHasLegacyThresholds(t *testing.T) {
ptrFloat := func(v float64) *float64 { return &v }