mattrguerra/better-memory-pipelinemainPrivate on GitHub, published here in full

test_content_gate.py

Language Python3.1 KB78 lines

tests/test_content_gate.py

  1. """content_gate.py: frontmatter flags, line patterns, remove vs redact, fail-closed."""
  2. import json
  3. import shutil
  4. import tempfile
  5. import unittest
  6. from pathlib import Path
  7. from helpers import load, run
  8. class ContentGateTest(unittest.TestCase):
  9. def setUp(self):
  10. self.dir = Path(tempfile.mkdtemp(prefix="bm-cg-"))
  11. (self.dir / "clean.md").write_text("# Clean\n\nNothing to see.\n")
  12. (self.dir / "flagged.md").write_text("---\nprivate: true\n---\n# Flagged\n")
  13. (self.dir / "visibility.md").write_text("---\nvisibility: 'Private'\n---\n# V\n")
  14. (self.dir / "marker.md").write_text("# Mixed\n\nkeep this\nnot this %% bm:private %%\nkeep too\n")
  15. (self.dir / "ssn.txt").write_text("id 123-45-6789\n")
  16. (self.dir / "binary.md").write_bytes(b"\xff\xfe not utf-8\n")
  17. (self.dir / "photo.png").write_bytes(b"\x89PNG")
  18. def tearDown(self):
  19. shutil.rmtree(self.dir, ignore_errors=True)
  20. def gate(self, mode):
  21. return load("content_gate.py", {"BM_STAGING_DIR": str(self.dir), "BM_GATE_MODE": mode})
  22. def names(self):
  23. return sorted(p.name for p in self.dir.iterdir())
  24. def report(self):
  25. return json.loads((self.dir / "gate-report.json").read_text())
  26. def test_remove_mode(self):
  27. code, _ = run(self.gate("remove"))
  28. self.assertEqual(code, 0)
  29. self.assertEqual(self.names(), ["clean.md", "gate-report.json", "photo.png"])
  30. r = self.report()
  31. self.assertEqual(r["passed"], 1)
  32. self.assertEqual(len(r["removed"]), 5)
  33. def test_redact_mode(self):
  34. run(self.gate("redact"))
  35. self.assertNotIn("flagged.md", self.names()) # frontmatter still removes
  36. self.assertNotIn("visibility.md", self.names())
  37. marker = (self.dir / "marker.md").read_text()
  38. self.assertIn("keep this", marker)
  39. self.assertIn("keep too", marker)
  40. self.assertIn("[[bm-gated]]", marker)
  41. self.assertNotIn("not this", marker)
  42. self.assertIn("[[bm-gated]]", (self.dir / "ssn.txt").read_text())
  43. self.assertEqual(sorted(self.report()["redacted"]), ["marker.md", "ssn.txt"])
  44. def test_txt_files_are_scanned(self):
  45. run(self.gate("remove"))
  46. self.assertNotIn("ssn.txt", self.names())
  47. def test_undecodable_file_is_pulled_not_crashed_on(self):
  48. code, _ = run(self.gate("remove"))
  49. self.assertEqual(code, 0)
  50. self.assertNotIn("binary.md", self.names())
  51. self.assertIn("binary.md (unreadable, fail-closed)", self.report()["removed"])
  52. def test_unknown_mode_refuses(self):
  53. code, _ = run(self.gate("remvoe"))
  54. self.assertEqual(code, 2)
  55. self.assertIn("flagged.md", self.names()) # nothing touched
  56. self.assertFalse((self.dir / "gate-report.json").exists())
  57. def test_placeholder_path_refuses(self):
  58. mod = load("content_gate.py", {"BM_STAGING_DIR": "/Users/CHANGEME/cowork-staging/staging",
  59. "BM_GATE_MODE": "remove"})
  60. code, _ = run(mod)
  61. self.assertEqual(code, 2)
  62. if __name__ == "__main__":
  63. unittest.main()