mirror of
https://github.com/safishamsi/graphify.git
synced 2026-09-24 14:35:46 +00:00
test(watch): assert update writes community_name (#1855 followup); changelog
Adds the regression test the #1855 fix was missing: _rebuild_code must produce graph.json whose clustered nodes carry community_name, guarding against the label-stripping regression recurring. Also records #1847 and #1855 in the 0.9.15 changelog. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
6eb5923404
commit
961b78e57a
@@ -4,6 +4,10 @@ Full release notes with details on each version: [GitHub Releases](https://githu
|
||||
|
||||
## 0.9.15 (2026-07-13)
|
||||
|
||||
- Fix: detection now honors nested `.gitignore`/`.graphifyignore` files below the scan root, not just those at the scan root and above (#1847, thanks @Mohak-Agrawal). git applies a `.gitignore` to everything under its own directory, but graphify only loaded ignore files from the VCS-root-down-to-scan-root chain — so a `vendor/sub/.gitignore` deeper in the tree was never read and its exclusions leaked into the graph. Each directory's own ignore files are now read during the walk and anchored to that directory, preserving last-match-wins precedence (nearer files win, including over `.git/info/exclude`) and the parent-exclusion rule.
|
||||
|
||||
- Fix: `graphify update` now writes human-readable `community_name` labels, not just numeric community ids (#1808 / #1855, thanks @latreon). The incremental rebuild in `_rebuild_code` called `to_json` without `community_labels`, so every `update`/hook rebuild stripped the labels a `cluster-only` pass had written; a follow-up `cluster-only` restored them and the next rebuild stripped them again. The rebuild now forwards the labels it already computes (hub-derived for a code-only pass) and strips `community_name` from the topology fast-path comparison so the new field doesn't force a needless re-cluster.
|
||||
|
||||
- Security: fix a stored XSS and broken neighbor links in the exported `graph.html` (#1838, thanks @edgestack-ai). The report's neighbor "focus" links dropped an unescaped `JSON.stringify(nid)` into a double-quoted inline `onclick`. Because the stringified value carries its own quotes, the attribute was truncated on every node — so the links never worked — and a node `id`/`label` containing a double-quote broke out of the attribute and injected live handlers. AST node ids are `[a-z0-9_]`-safe, but ids/labels from documents or from titles scraped via `graphify add <url>` are not, so a hostile source could plant an executable handler into a report opened locally. The id is now carried in an HTML-escaped `data-nid` attribute and dispatched through a single delegated listener, closing the injection and repairing the links.
|
||||
|
||||
## 0.9.14 (2026-07-12)
|
||||
|
||||
@@ -160,6 +160,34 @@ def test_graphify_root_preserves_relative_when_invoked_with_relative_path(tmp_pa
|
||||
)
|
||||
|
||||
|
||||
def test_rebuild_code_writes_community_name(tmp_path):
|
||||
"""#1808: `graphify update` / _rebuild_code must forward community_labels to
|
||||
to_json, so graph.json nodes carry a human-readable community_name (hub-derived
|
||||
for a code-only rebuild) — not just a numeric community id. Before the fix,
|
||||
_rebuild_code called to_json without community_labels, so the labels a
|
||||
cluster-only pass writes were stripped again on every incremental rebuild."""
|
||||
import json
|
||||
from graphify.watch import _rebuild_code
|
||||
|
||||
corpus = tmp_path / "corpus"
|
||||
corpus.mkdir()
|
||||
(corpus / "a.py").write_text(
|
||||
"def alpha():\n return beta()\n\ndef beta():\n return 1\n", encoding="utf-8"
|
||||
)
|
||||
(corpus / "b.py").write_text(
|
||||
"import a\n\ndef gamma():\n return a.alpha()\n", encoding="utf-8"
|
||||
)
|
||||
assert _rebuild_code(corpus, acquire_lock=False) is True
|
||||
|
||||
graph = json.loads((corpus / "graphify-out" / "graph.json").read_text(encoding="utf-8"))
|
||||
clustered = [n for n in graph["nodes"] if n.get("community") is not None]
|
||||
assert clustered, "expected clustered nodes in the rebuilt graph"
|
||||
assert all(n.get("community_name") for n in clustered), (
|
||||
"clustered nodes missing community_name — the update rebuild stripped the "
|
||||
"labels that cluster-only writes (#1808)"
|
||||
)
|
||||
|
||||
|
||||
def test_graphify_root_preserves_absolute_when_user_supplied(tmp_path):
|
||||
"""When the caller supplies an absolute path, ``.graphify_root`` stores
|
||||
that absolute form verbatim — preserving explicit-absolute intent."""
|
||||
|
||||
Reference in New Issue
Block a user