Files
obsidian-wiki/tests/test_upstream_compat.py
T
Codex 82890606aa feat(wiki): sync upstream v2026.10.4 core maintenance
Selectively port source hashing, locked manifest/memory writes, path-aware
link lint and graph analysis, and revision-checked staging from upstream
4f457e154653756b04802d5aeb25c20f42b4770c. Record source hashes and exclusions.

Preserve local archive/catalog citations, curated manifest metadata, config
location, file-index and MCP behavior. Wire maintenance guidance into four
skills without migrating vault contents or changing running services.

Validation: 609 tests passed, including existing MCP/file-asset regressions
and imported upstream maintenance tests. Read-only vault status left shared
metadata hashes unchanged. Wiki MCP remains inactive; orders MCP is active.
2026-10-31 12:39:48 +00:00

86 lines
3.8 KiB
Python

"""Local data contracts that the selected upstream port must preserve."""
import json
from pathlib import Path
import pytest
from obsidian_wiki.cli import main
from obsidian_wiki.graph_analysis import parse_vault_graph
from obsidian_wiki.lint import lint_vault
from obsidian_wiki.provenance import archive_wikilink_relpath, resolve_source_key
from obsidian_wiki.vault import iter_md
@pytest.mark.parametrize("shape", ["dict", "list"])
def test_cache_cli_preserves_curated_metadata_and_page_associations(tmp_path, shape):
source = tmp_path / "source.pdf"
source.write_bytes(b"new revision")
entry = {
"path": "source.pdf", "pages_produced": ["concepts/a.md"],
"archive_path": "_sources/archive/a.pdf", "content_hash": "old",
"bjd_part_numbers": ["BJD-123"], "competitor_part_numbers": ["OTHER-456"],
"series": ["WTB"], "pin_count": [6], "pitch": [2.0],
"catalog_paths": ["_sources/catalog/a.md"], "visibility": "internal",
}
sources = {"source.pdf": entry} if shape == "dict" else [entry]
manifest = tmp_path / ".manifest.json"
manifest.write_text(json.dumps({"sources": sources, "local_revision": 7}))
assert main(["cache-update", str(tmp_path), str(source)]) == 0
updated = json.loads(manifest.read_text())
actual = updated["sources"]["source.pdf"] if shape == "dict" else updated["sources"][0]
assert updated["local_revision"] == 7
for key, value in entry.items():
if key != "content_hash":
assert actual[key] == value
assert actual["content_hash"] != "old"
def test_local_sources_are_citable_but_not_knowledge_pages(tmp_path):
refs = ["_sources/archive/doc.pdf", "_sources/catalog/products.md"]
for rel in [*refs, "_sources/archive/raw.md", "_meta/taxonomy.md", "_inbox/draft.md", "_bot_exports/copy.md"]:
p = tmp_path / rel
p.parent.mkdir(parents=True, exist_ok=True)
p.write_text("Raw source, not a knowledge page")
page = tmp_path / "concepts" / "a.md"
page.parent.mkdir()
page.write_text(
"---\ntitle: A\ncategory: concepts\ntags: [a]\nsources: []\n"
"created: 2026-10-01\nupdated: 2026-10-01\nsummary: Example\n---\n"
+ " ".join(f"[[{rel}]]" for rel in refs)
)
assert iter_md(tmp_path) == [page]
graph, _ = parse_vault_graph(tmp_path)
assert set(graph) == {"a"}
assert graph["a"] == []
findings = lint_vault(tmp_path, require_trust_ledger=False)["findings"]
assert findings["broken_links"] == []
assert resolve_source_key(tmp_path, refs[0]) == refs[0]
assert archive_wikilink_relpath(tmp_path, refs[0] + "|PDF") == refs[0]
assert archive_wikilink_relpath(tmp_path, "_sources/catalog/products") == refs[1]
@pytest.mark.parametrize("target", ["../_sources/archive/a.pdf", "/tmp/_sources/archive/a.pdf"])
def test_local_source_resolution_refuses_paths_outside_vault(tmp_path, target):
assert resolve_source_key(tmp_path, target) is None
assert archive_wikilink_relpath(tmp_path, target) is None
def test_staging_cli_conflict_keeps_reviewed_and_live_files(tmp_path, capsys):
staged = tmp_path / "_staging/concepts/a.md"
staged.parent.mkdir(parents=True)
staged.write_text("Reviewed proposal")
assert main(["staging", "list", "--vault", str(tmp_path), "--json"]) == 0
inventory = json.loads(capsys.readouterr().out)
# The runtime schema is asserted here so the skill can pin listed revisions.
entry = inventory[0]
live = tmp_path / "concepts/a.md"
live.parent.mkdir()
live.write_text("Concurrent live update")
assert main([
"staging", "promote", entry["staged_path"], "--vault", str(tmp_path),
"--expect-staged", entry["staged_revision"], "--expect-new",
]) == 9
assert live.read_text() == "Concurrent live update"
assert staged.read_text() == "Reviewed proposal"