package topology
import (
"os/exec"
"strings"
"testing"
)
func TestRenderSVGIncludesTopologyNodesAndDirectedEdge(t *testing.T) {
servers := []map[string]string{
{"ServerID": "commit", "Services": "commit-server", "Address": "commit.example.com:1666"},
{"ServerID": "edge", "Services": "edge-server", "Address": "edge.example.com:1666"},
}
records := []map[string]string{{"ServerID": "edge", "TargetServerID": "commit"}}
svg, err := RenderSVG("Test topology", servers, records)
if err != nil {
t.Fatalf("RenderSVG() error = %v", err)
}
for _, expected := range []string{
"<svg", "Test topology", "commit", "edge", "marker-end:url(#arrow)",
"data-source=\"edge\"", "data-id=\"commit\"", "id=\"save-button\"",
"function refreshEdges()", "function saveDiagram()",
} {
if !strings.Contains(svg, expected) {
t.Errorf("RenderSVG() did not contain %q", expected)
}
}
}
func TestRenderNormalizedSVGIncludesServerDetailsAndHostNodes(t *testing.T) {
servers := []Server{
{ServerID: "commit", ServerType: "commit-server"},
{ServerID: "edge", ServerType: "edge-server", Host: "edge.example.com", Port: "1666", Target: "commit", Version: "P4D/2026.1", Notes: []string{"test edge"}},
}
svg, err := RenderNormalizedSVG("Test topology", servers)
if err != nil {
t.Fatalf("RenderNormalizedSVG() error = %v", err)
}
for _, expected := range []string{
"p4server: edge", "type: edge-server", "port: 1666", "target: commit", "version: P4D/2026.1", "note: test edge",
"host-edge", "address: edge.example.com", "edge host-edge",
} {
if !strings.Contains(svg, expected) {
t.Errorf("RenderNormalizedSVG() did not contain %q", expected)
}
}
}
func TestRenderNormalizedSVGHandlesCyclesAndDisconnectedComponents(t *testing.T) {
servers := []Server{
{ServerID: "root-a", ServerType: "commit-server"},
{ServerID: "edge-a", ServerType: "edge-server", Target: "root-a"},
{ServerID: "root-b", ServerType: "commit-server"},
{ServerID: "edge-b", ServerType: "edge-server", Target: "root-b"},
{ServerID: "cycle-a", ServerType: "broker", Target: "cycle-b"},
{ServerID: "cycle-b", ServerType: "broker", Target: "cycle-a"},
}
svg, err := RenderNormalizedSVG("Test topology", servers)
if err != nil {
t.Fatalf("RenderNormalizedSVG() error = %v", err)
}
for _, id := range []string{"root-a", "edge-a", "root-b", "edge-b", "cycle-a", "cycle-b"} {
if !strings.Contains(svg, "data-id=\""+id+"\"") {
t.Errorf("RenderNormalizedSVG() did not render %q", id)
}
}
}
func TestRenderNormalizedSVGWithSFDPLayout(t *testing.T) {
if _, err := exec.LookPath("sfdp"); err != nil {
t.Skip("Graphviz sfdp is not installed")
}
servers := []Server{
{ServerID: "commit", ServerType: "commit-server"},
{ServerID: "edge-a", ServerType: "edge-server", Target: "commit"},
{ServerID: "edge-b", ServerType: "edge-server", Target: "commit"},
}
svg, err := RenderNormalizedSVGWithLayout("Test topology", servers, "sfdp")
if err != nil {
t.Fatalf("RenderNormalizedSVGWithLayout() error = %v", err)
}
for _, id := range []string{"commit", "edge-a", "edge-b", "host-commit"} {
if !strings.Contains(svg, "data-id=\""+id+"\"") {
t.Errorf("SFDP SVG did not render %q", id)
}
}
}