forked from kay/RouterOS
Übersicht: Interface-Klick hebt transitiv alle zusammenhängenden Linien hervor
OverviewGraph.highlightedNodeIDs(startingAt:) macht für Interface-Knoten eine BFS über alle Kanten statt nur 1-Hop-Matching, damit z.B. "DHCP-Server -> Pool" oder "IP-Adresse -> DHCP-Netzwerk" mit sichtbar werden. Andere Knotentypen bleiben unverändert bei 1-Hop. Logik isoliert unit-getestet (GUI selbst nicht automatisiert klickbar). 61 Tests grün. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YDmUd93KxsYGr2kLTotWnG
This commit is contained in:
@@ -173,4 +173,40 @@ final class OverviewGraphTests: XCTestCase {
|
||||
let route = graph.nodes.first { $0.id == "route:0" }
|
||||
XCTAssertNil(route?.editTarget)
|
||||
}
|
||||
|
||||
/// Clicking an Interface should highlight every line that traces back to it, not just the
|
||||
/// ones directly touching it — e.g. a DHCP server's own pool, or an IP address's DHCP-network
|
||||
/// options, sit a second hop away from the interface itself. Confirmed scope (2026-09-15):
|
||||
/// only interfaces expand this way — every other node kind stays one-hop-only.
|
||||
func testHighlightedNodeIDsExpandsTransitivelyOnlyForInterfaces() {
|
||||
let graph = OverviewViewModel.buildGraph(
|
||||
interfaces: [item(["name": "ether1", "type": "ether"])],
|
||||
bridgePorts: [], vlans: [], wireguardPeers: [],
|
||||
addresses: [item(["address": "192.168.88.1/24", "interface": "ether1", "network": "192.168.88.0"])],
|
||||
pools: [item(["name": "pool1", "ranges": "192.168.88.10-192.168.88.254"])],
|
||||
dhcpServers: [item(["name": "dhcp1", "interface": "ether1", "address-pool": "pool1"])],
|
||||
dhcpNetworks: [item(["address": "192.168.88.0/24", "gateway": "192.168.88.1"])],
|
||||
dhcpClients: [], routes: [], filterRules: [], natRules: [], addressLists: []
|
||||
)
|
||||
|
||||
let interfaceID = "Interfaces:ether1"
|
||||
let addressID = "IP-Adressen:192.168.88.1/24"
|
||||
let dhcpServerID = "Pools & DHCP:dhcp:dhcp1"
|
||||
let poolID = "Pools & DHCP:pool:pool1"
|
||||
let dhcpNetworkID = "Pools & DHCP:dhcpnet:192.168.88.0/24"
|
||||
|
||||
// Sanity: the pool and the DHCP-network options really are two hops away from the
|
||||
// interface (no direct edge to either) — otherwise this test wouldn't distinguish
|
||||
// transitive-closure behavior from plain one-hop matching.
|
||||
XCTAssertFalse(graph.edges.contains { $0.from == interfaceID && $0.to == poolID })
|
||||
XCTAssertFalse(graph.edges.contains { $0.from == interfaceID && $0.to == dhcpNetworkID })
|
||||
|
||||
let fromInterface = graph.highlightedNodeIDs(startingAt: interfaceID)
|
||||
XCTAssertEqual(fromInterface, [interfaceID, addressID, dhcpServerID, poolID, dhcpNetworkID])
|
||||
|
||||
// A non-interface node (e.g. the pool) stays one-hop-only: just itself, regardless of
|
||||
// what it's connected to.
|
||||
XCTAssertEqual(graph.highlightedNodeIDs(startingAt: poolID), [poolID])
|
||||
XCTAssertEqual(graph.highlightedNodeIDs(startingAt: addressID), [addressID])
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user