package app import "testing" func TestNormalizeTransportIfaceID(t *testing.T) { cases := []struct { in string want string }{ {"", transportDefaultIfaceID}, {" ", transportDefaultIfaceID}, {"Shared", "shared"}, {"sb Main", "sb-main"}, } for _, tc := range cases { if got := normalizeTransportIfaceID(tc.in); got != tc.want { t.Fatalf("normalizeTransportIfaceID(%q)=%q want=%q", tc.in, got, tc.want) } } } func TestNormalizeTransportInterfacesStateAddsSharedAndClientIfaceIDs(t *testing.T) { st := transportInterfacesState{ Version: transportStateVersion, Items: []TransportInterface{ {ID: "edge-eu", Name: "", Mode: ""}, }, } clients := []TransportClient{ {ID: "c1", IfaceID: ""}, {ID: "c2", IfaceID: "lab-net"}, } norm, changed := normalizeTransportInterfacesState(st, clients) if !changed { t.Fatalf("expected normalization changes") } if len(norm.Items) != 3 { t.Fatalf("expected 3 interfaces, got %d", len(norm.Items)) } want := map[string]TransportInterfaceMode{ "edge-eu": TransportInterfaceModeDedicated, transportDefaultIfaceID: TransportInterfaceModeShared, "lab-net": TransportInterfaceModeDedicated, } wantTable := map[string]string{ "edge-eu": "agvpn_if_edge_eu", transportDefaultIfaceID: "", "lab-net": "agvpn_if_lab_net", } for _, it := range norm.Items { mode, ok := want[it.ID] if !ok { t.Fatalf("unexpected interface id %q", it.ID) } if it.Mode != mode { t.Fatalf("interface %q mode=%q want=%q", it.ID, it.Mode, mode) } if it.Name == "" { t.Fatalf("interface %q has empty name", it.ID) } if got := it.RoutingTable; got != wantTable[it.ID] { t.Fatalf("interface %q routing_table=%q want=%q", it.ID, got, wantTable[it.ID]) } delete(want, it.ID) } if len(want) != 0 { t.Fatalf("missing interfaces: %#v", want) } } func TestBuildTransportInterfaceItemsAggregatesClients(t *testing.T) { ifaces := []TransportInterface{ {ID: transportDefaultIfaceID, Name: "Shared interface", Mode: TransportInterfaceModeShared}, {ID: "lab-net", Name: "Lab net", Mode: TransportInterfaceModeDedicated, RoutingTable: "agvpn_if_lab_net"}, } clients := []TransportClient{ {ID: "c-up-1", IfaceID: "lab-net", Status: TransportClientUp}, {ID: "c-down", IfaceID: "lab-net", Status: TransportClientDown}, {ID: "c-up-2", IfaceID: "", Status: TransportClientUp}, } items := buildTransportInterfaceItems(ifaces, clients) if len(items) != 2 { t.Fatalf("expected 2 items, got %d", len(items)) } if items[0].ID != "lab-net" { t.Fatalf("expected first item lab-net, got %q", items[0].ID) } if items[0].ClientCount != 2 || items[0].UpCount != 1 { t.Fatalf("unexpected lab-net counters: %#v", items[0]) } if items[0].RoutingTable != "agvpn_if_lab_net" { t.Fatalf("unexpected lab-net routing_table: %q", items[0].RoutingTable) } if items[1].ID != transportDefaultIfaceID { t.Fatalf("expected second item shared, got %q", items[1].ID) } if items[1].ClientCount != 1 || items[1].UpCount != 1 { t.Fatalf("unexpected shared counters: %#v", items[1]) } } func TestAppendTransportVirtualInterfaceItemsAddsAdGuardRow(t *testing.T) { items := []TransportInterfaceItem{ {ID: transportDefaultIfaceID, Name: "Shared interface", Mode: TransportInterfaceModeShared, ClientCount: 2, UpCount: 1}, } virtual := []TransportClient{{ ID: transportPolicyTargetAdGuardID, Name: "AdGuard VPN", Kind: TransportClientKind(transportPolicyTargetAdGuardID), IfaceID: transportPolicyTargetAdGuardIfaceID, Iface: "tun0", RoutingTable: transportPolicyTargetAdGuardTable, Status: TransportClientUp, UpdatedAt: "2026-03-22T00:00:00Z", }} out := appendTransportVirtualInterfaceItems(items, virtual) if len(out) != 2 { t.Fatalf("expected 2 rows with virtual item, got %d", len(out)) } var adg *TransportInterfaceItem var shared *TransportInterfaceItem for i := range out { if out[i].ID == transportPolicyTargetAdGuardID { adg = &out[i] } if out[i].ID == transportDefaultIfaceID { shared = &out[i] } } if adg == nil { t.Fatalf("missing adguard virtual row") } if adg.ClientCount != 1 || adg.UpCount != 1 { t.Fatalf("unexpected adguard counters: %#v", *adg) } if adg.RoutingTable != transportPolicyTargetAdGuardTable { t.Fatalf("unexpected adguard routing table: %q", adg.RoutingTable) } if shared == nil || shared.ClientCount != 2 || shared.UpCount != 1 { t.Fatalf("shared row was modified unexpectedly: %#v", shared) } }