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

Add modal graph node inspection

This commit is contained in:
Andraxion 2026-07-24 21:01:53 -04:00
parent 5f3d938adc
commit 4c82e1643d
13 changed files with 179 additions and 25 deletions

View file

@ -2,6 +2,7 @@ from __future__ import annotations
import json
import shutil
import subprocess
import tempfile
import unittest
import urllib.error
@ -13,6 +14,7 @@ from docforge.errors import DocForgeError
from docforge.index import ProjectIndex
from docforge.project import Project
from docforge.visualization import (
_GRAPH_BROWSER_HTML,
VISUALIZATION_TEMPLATE,
VisualizationIndexSnapshot,
VisualizationRunner,
@ -59,6 +61,21 @@ class VisualizationTests(unittest.TestCase):
with self.assertRaisesRegex(DocForgeError, "safety boundary"):
snapshot.node("guide.workflow", depth=1, limit=401)
@unittest.skipUnless(shutil.which("node"), "Node.js is required for embedded script validation")
def test_embedded_browser_javascript_is_valid(self) -> None:
script = _GRAPH_BROWSER_HTML.split("<script>", 1)[1].split("</script>", 1)[0]
with tempfile.TemporaryDirectory() as directory:
path = Path(directory) / "graph-browser.js"
path.write_text(script, encoding="utf-8")
result = subprocess.run(
["node", "--check", str(path)],
check=False,
capture_output=True,
text=True,
)
self.assertEqual("", result.stderr)
self.assertEqual(0, result.returncode)
def test_runner_serves_only_token_bound_read_only_graph_endpoints(self) -> None:
with tempfile.TemporaryDirectory() as directory:
root = self.copy_fixture("alpha", Path(directory))
@ -84,8 +101,13 @@ class VisualizationTests(unittest.TestCase):
self.assertIn('id="zoom-in"', html)
self.assertIn('id="zoom-out"', html)
self.assertIn('id="reset-view"', html)
self.assertIn('id="node-dialog"', html)
self.assertIn('id="explore-node"', html)
self.assertIn('addEventListener("wheel"', html)
self.assertIn('addEventListener("pointermove"', html)
self.assertIn("inspectNode(node.node_id)", html)
self.assertIn('dialog.showModal()', html)
self.assertIn("await loadNode(nodeId)", html)
self.assertIn("left-drag to pan", html)
self.assertIn("default-src 'none'", headers["Content-Security-Policy"])
self.assertEqual("no-store", headers["Cache-Control"])