Pulse/internal/config/availability_test.go
2026-06-29 22:43:13 +01:00

163 lines
4.8 KiB
Go

package config
import "testing"
func TestNormalizeAvailabilityTargetPreservesHTTPAddress(t *testing.T) {
target := NormalizeAvailabilityTarget(AvailabilityTarget{
ID: " target-1 ",
Name: " Status page ",
Address: " https://device.local/status?ready=1 ",
Protocol: AvailabilityProbeHTTP,
Path: " health ",
Enabled: true,
})
if target.ID != "target-1" {
t.Fatalf("ID = %q, want target-1", target.ID)
}
if target.Name != "Status page" {
t.Fatalf("Name = %q, want Status page", target.Name)
}
if target.TargetKind != AvailabilityTargetService {
t.Fatalf("TargetKind = %q, want %q", target.TargetKind, AvailabilityTargetService)
}
if target.Address != "https://device.local/status?ready=1" {
t.Fatalf("Address = %q, want preserved HTTP URL", target.Address)
}
if target.Path != "health" {
t.Fatalf("Path = %q, want health", target.Path)
}
}
func TestNormalizeAvailabilityTargetReducesICMPAddressToHost(t *testing.T) {
target := NormalizeAvailabilityTarget(AvailabilityTarget{
Address: " https://device.local:8443/status ",
Protocol: AvailabilityProbeICMP,
Enabled: true,
})
if target.Address != "device.local" {
t.Fatalf("Address = %q, want device.local", target.Address)
}
if target.Port != 0 {
t.Fatalf("Port = %d, want 0", target.Port)
}
}
func TestNormalizeAvailabilityTargetAcceptsPingAlias(t *testing.T) {
target := NormalizeAvailabilityTarget(AvailabilityTarget{
Address: " https://device.local:8443/status ",
Protocol: AvailabilityProbeProtocol(" Ping "),
Enabled: true,
})
if target.Protocol != AvailabilityProbeICMP {
t.Fatalf("Protocol = %q, want %q", target.Protocol, AvailabilityProbeICMP)
}
if target.Address != "device.local" {
t.Fatalf("Address = %q, want device.local", target.Address)
}
}
func TestAvailabilityTargetProbeAddressUsesHTTPHostname(t *testing.T) {
target := NormalizeAvailabilityTarget(AvailabilityTarget{
Address: "http://solar-inverter.lab.local/status",
Protocol: AvailabilityProbeHTTP,
Enabled: true,
})
if got := target.ProbeAddress(); got != "solar-inverter.lab.local" {
t.Fatalf("ProbeAddress() = %q, want solar-inverter.lab.local", got)
}
}
func TestAvailabilityTargetHTTPURLAppliesPortAndPath(t *testing.T) {
target := NormalizeAvailabilityTarget(AvailabilityTarget{
Address: "device.local/status",
Protocol: AvailabilityProbeHTTP,
Port: 8080,
Path: "health",
Enabled: true,
})
u, err := target.HTTPURL()
if err != nil {
t.Fatalf("HTTPURL() error = %v", err)
}
if got := u.String(); got != "http://device.local:8080/health" {
t.Fatalf("HTTPURL() = %q, want http://device.local:8080/health", got)
}
}
func TestAvailabilityTargetValidateRejectsTCPWithoutPort(t *testing.T) {
target := NormalizeAvailabilityTarget(AvailabilityTarget{
Address: "device.local",
Protocol: AvailabilityProbeTCP,
Enabled: true,
})
if err := target.Validate(); err == nil {
t.Fatal("Validate() error = nil, want TCP port error")
}
}
func TestAvailabilityTargetValidateAcceptsPingAlias(t *testing.T) {
target := AvailabilityTarget{
TargetKind: AvailabilityTargetService,
Address: "device.local",
Protocol: AvailabilityProbeProtocol("ping"),
Enabled: true,
}
if err := target.Validate(); err != nil {
t.Fatalf("Validate() error = %v, want nil", err)
}
}
func TestAvailabilityTargetValidateRejectsUnsupportedTargetKind(t *testing.T) {
target := NormalizeAvailabilityTarget(AvailabilityTarget{
TargetKind: AvailabilityTargetKind("database"),
Address: "device.local",
Protocol: AvailabilityProbeICMP,
Enabled: true,
})
if err := target.Validate(); err == nil {
t.Fatal("Validate() error = nil, want target kind error")
}
}
func TestAvailabilityTargetsRoundTripThroughPersistence(t *testing.T) {
persistence := NewConfigPersistence(t.TempDir())
targets := []AvailabilityTarget{
{
ID: "endpoint-1",
Name: "Energy monitor",
TargetKind: AvailabilityTargetDevice,
Address: "device.local",
Protocol: AvailabilityProbeICMP,
Enabled: true,
},
}
if err := persistence.SaveAvailabilityTargets(targets); err != nil {
t.Fatalf("SaveAvailabilityTargets() error = %v", err)
}
loaded, err := persistence.LoadAvailabilityTargets()
if err != nil {
t.Fatalf("LoadAvailabilityTargets() error = %v", err)
}
if len(loaded) != 1 {
t.Fatalf("LoadAvailabilityTargets() length = %d, want 1", len(loaded))
}
if loaded[0].Name != "Energy monitor" {
t.Fatalf("loaded name = %q, want Energy monitor", loaded[0].Name)
}
if loaded[0].TargetKind != AvailabilityTargetDevice {
t.Fatalf("loaded target kind = %q, want %q", loaded[0].TargetKind, AvailabilityTargetDevice)
}
if loaded[0].PollIntervalSecs != DefaultAvailabilityPollIntervalSecs {
t.Fatalf("poll interval = %d, want default", loaded[0].PollIntervalSecs)
}
}