1
0
Fork 0
Code Issues Pull requests Projects Releases 2 Packages Wiki Activity Actions Pages

Redesign graph viewer navigation

This commit is contained in:
Andraxion 2026-07-24 23:15:57 -04:00
parent 7834461eb9
commit 9bd41c5982
8 changed files with 354 additions and 72 deletions

View file

@ -101,7 +101,7 @@ class DocForgeMcpTests(unittest.IsolatedAsyncioTestCase):
visualization = results[11].structuredContent["visualization"]
self.assertTrue(visualization["read_only"])
self.assertTrue(visualization["project_bound"])
self.assertEqual("graph-browser@6", visualization["template"])
self.assertEqual("graph-browser@7", visualization["template"])
self.assertEqual("browser_lease", visualization["lifetime"]["policy"])
self.assertTrue(visualization["url"].startswith("http://127.0.0.1:"))
context = results[8].structuredContent

View file

@ -42,6 +42,7 @@ class VisualizationTests(unittest.TestCase):
overview = snapshot.overview()
first = snapshot.node("guide.workflow", depth=2, limit=2)
second = snapshot.node("guide.workflow", depth=2, limit=2)
filtered = snapshot.filter_nodes(category="tag", value="canonical", limit=2)
self.assertEqual(3, overview["node_count"])
self.assertEqual(2, overview["edge_count"])
@ -54,6 +55,10 @@ class VisualizationTests(unittest.TestCase):
)
self.assertEqual(first, second)
self.assertEqual("guide.workflow", first["root"])
self.assertEqual(1, filtered["count"])
self.assertEqual(1, filtered["total"])
self.assertFalse(filtered["truncated"])
self.assertEqual("guide.foundation", filtered["results"][0]["node_id"])
self.assertLessEqual(len(first["edges"]), 2)
self.assertIn(
"guide.workflow",
@ -62,6 +67,8 @@ class VisualizationTests(unittest.TestCase):
with self.assertRaisesRegex(DocForgeError, "safety boundary"):
snapshot.node("guide.workflow", depth=1, limit=401)
with self.assertRaisesRegex(DocForgeError, "category is unsupported"):
snapshot.filter_nodes(category="relation", value="depends_on", limit=2)
@unittest.skipUnless(shutil.which("node"), "Node.js is required for embedded script validation")
def test_embedded_browser_javascript_is_valid(self) -> None:
@ -173,17 +180,25 @@ if (centered.y !== positions.get("child-two").y - 150) fail("center y");
self.assertIn('id="zoom-out"', html)
self.assertIn('id="reset-view"', html)
self.assertIn('id="node-dialog"', html)
self.assertIn('id="node-card"', html)
self.assertIn('id="explore-node"', html)
self.assertIn('id="explore-card-node"', html)
self.assertIn('id="left-resizer"', html)
self.assertIn('id="right-resizer"', html)
self.assertIn('id="view-nodes"', html)
self.assertIn('id="view-flow"', html)
self.assertIn('id="neighborhood-sections"', html)
self.assertNotIn('id="details"', html)
self.assertIn(".empty[hidden] { display: none; }", html)
self.assertIn("html, body { height: 100%; overflow: hidden; }", html)
self.assertIn("Space centers selection", html)
self.assertIn("resize: both", html)
self.assertNotIn("backdrop-filter", html)
self.assertIn('addEventListener("wheel"', html)
self.assertIn('addEventListener("pointermove"', html)
self.assertIn("inspectNode(node.node_id)", html)
self.assertIn("showNodeCard(node.node_id)", html)
self.assertIn('addEventListener("contextmenu"', html)
self.assertIn("dialog.showModal()", html)
self.assertIn("await loadNode(nodeId)", html)
self.assertIn("beginDialogDrag", html)
@ -194,6 +209,9 @@ if (centered.y !== positions.get("child-two").y - 150) fail("center y");
self.assertIn("distanceShade", html)
self.assertIn("viewportForPositions", html)
self.assertIn("centerSelectedNode", html)
self.assertIn("filterByDescriptor", html)
self.assertIn("api(`filter?${params}`)", html)
self.assertIn('setViewMode("flow")', html)
self.assertIn('event.code !== "Space"', html)
self.assertIn('class: "selection-ring"', html)
self.assertIn("renewViewerLease", html)
@ -205,7 +223,7 @@ if (centered.y !== positions.get("child-two").y - 150) fail("center y");
)[0]
self.assertNotIn("setPointerCapture", pointerdown)
self.assertIn("setPointerCapture", pointermove)
self.assertIn("left-drag pans", html)
self.assertIn("right-click full inspector", html)
self.assertIn("default-src 'none'", headers["Content-Security-Policy"])
self.assertEqual("no-store", headers["Cache-Control"])
self.assertEqual("DENY", headers["X-Frame-Options"])
@ -231,6 +249,19 @@ if (centered.y !== positions.get("child-two").y - 150) fail("center y");
self.assertEqual("alpha-docs", search["project_id"])
self.assertGreaterEqual(search["count"], 1)
filter_query = urllib.parse.urlencode(
{"category": "tag", "value": "canonical", "limit": overview["max_results"]}
)
with urllib.request.urlopen(
f"{base}api/filter?{filter_query}", timeout=2
) as response:
filtered = json.load(response)
self.assertEqual("alpha-docs", filtered["project_id"])
self.assertEqual("tag", filtered["category"])
self.assertEqual("canonical", filtered["value"])
self.assertEqual(1, filtered["total"])
self.assertEqual("guide.foundation", filtered["results"][0]["node_id"])
node_query = urllib.parse.urlencode(
{"id": "guide.workflow", "depth": 1, "limit": 20}
)