tests/test_no_private_paths.py
Rama main · réplica de lectura del repositorio original.
"""The tracked tree carries no private paths, hosts, addresses or session trailers.
Written after the 2026-08-19 scrub was undone twelve days later by ordinary
feature work: a scrub is a state, not a commit, and nothing was checking the
state.
The identifiers are not in the repository -- spelling them out, even in
fragments, would publish them. They are read, one per line, from the
environment variable JOBD_PRIVACY_FORBIDDEN (CI sets it from the
PRIVACY_FORBIDDEN repository secret) or else from
~/.config/jobd/privacy-forbidden.txt. With neither, both scan tests FAIL rather
than pass on an empty list. Hits are reported by entry number (#k), never by
the matched text, so a CI log cannot print what it found.
"""
from __future__ import annotations
import os
import subprocess
from pathlib import Path
import pytest
ROOT = Path(__file__).resolve().parents[1]
_ENV = "JOBD_PRIVACY_FORBIDDEN"
_FILE = Path.home() / ".config/jobd/privacy-forbidden.txt"
_raw = os.environ.get(_ENV) or (_FILE.read_text(encoding="utf-8") if _FILE.is_file() else "")
FORBIDDEN = [line.strip() for line in _raw.splitlines() if line.strip()]
def _require_list() -> None:
if not FORBIDDEN:
pytest.fail(f"no forbidden list: set {_ENV} or write {_FILE} (one identifier per line)")
def scan(paths: list[Path]) -> list[str]:
hits: list[str] = []
needles = [n.encode() for n in FORBIDDEN]
for p in paths:
try:
data = p.read_bytes()
except (IsADirectoryError, FileNotFoundError):
continue
for i, line in enumerate(data.split(b"\n"), 1):
for k, n in enumerate(needles, 1):
if n in line:
hits.append(f"{p.relative_to(ROOT) if p.is_relative_to(ROOT) else p}:{i}: #{k}")
return hits
def _tracked() -> list[Path]:
out = subprocess.run(
["git", "ls-files", "-z"], cwd=ROOT, capture_output=True, check=True
).stdout
return [ROOT / f.decode() for f in out.split(b"\0") if f]
def test_tracked_tree_has_no_private_paths():
_require_list()
files = _tracked()
assert Path(__file__) in files, "this guard must itself be tracked"
hits = scan(files)
assert hits == [], "private content is tracked:\n" + "\n".join(hits)
def test_scanner_reports_every_planted_hit(tmp_path):
"""Positive control: the scanner is worth exactly what it can catch."""
_require_list()
planted = tmp_path / "planted.bin"
planted.write_bytes(b"\x89PNG\n" + b"\n".join(n.encode() for n in FORBIDDEN) + b"\n")
hits = scan([planted])
found = {h.split(": ", 1)[1] for h in hits}
want = {f"#{k}" for k in range(1, len(FORBIDDEN) + 1)}
assert found == want, sorted(want - found)
assert all(h.split(":")[1].isdigit() for h in hits)
def test_the_private_overlay_is_gitignored():
"""The real roots and names live in config/projects.local.yaml. If git does
not ignore that path, the deploy step that copies it beside projects.yaml
turns the next `git add -A` into a publication of everything this file
exists to keep private. (#129 appended the rule as one line containing
literal backslash-n sequences, so the pattern never matched.)"""
r = subprocess.run(
["git", "check-ignore", "-q", "config/projects.local.yaml"], cwd=ROOT, check=False
)
assert r.returncode == 0, "config/projects.local.yaml is not gitignored"