test_content_gate.py
Language Python3.1 KB78 lines
"""content_gate.py: frontmatter flags, line patterns, remove vs redact, fail-closed."""import jsonimport shutilimport tempfileimport unittestfrom pathlib import Pathfrom helpers import load, runclass ContentGateTest(unittest.TestCase):def setUp(self):self.dir = Path(tempfile.mkdtemp(prefix="bm-cg-"))(self.dir / "clean.md").write_text("# Clean\n\nNothing to see.\n")(self.dir / "flagged.md").write_text("---\nprivate: true\n---\n# Flagged\n")(self.dir / "visibility.md").write_text("---\nvisibility: 'Private'\n---\n# V\n")(self.dir / "marker.md").write_text("# Mixed\n\nkeep this\nnot this %% bm:private %%\nkeep too\n")(self.dir / "ssn.txt").write_text("id 123-45-6789\n")(self.dir / "binary.md").write_bytes(b"\xff\xfe not utf-8\n")(self.dir / "photo.png").write_bytes(b"\x89PNG")def tearDown(self):shutil.rmtree(self.dir, ignore_errors=True)def gate(self, mode):return load("content_gate.py", {"BM_STAGING_DIR": str(self.dir), "BM_GATE_MODE": mode})def names(self):return sorted(p.name for p in self.dir.iterdir())def report(self):return json.loads((self.dir / "gate-report.json").read_text())def test_remove_mode(self):code, _ = run(self.gate("remove"))self.assertEqual(code, 0)self.assertEqual(self.names(), ["clean.md", "gate-report.json", "photo.png"])r = self.report()self.assertEqual(r["passed"], 1)self.assertEqual(len(r["removed"]), 5)def test_redact_mode(self):run(self.gate("redact"))self.assertNotIn("flagged.md", self.names()) # frontmatter still removesself.assertNotIn("visibility.md", self.names())marker = (self.dir / "marker.md").read_text()self.assertIn("keep this", marker)self.assertIn("keep too", marker)self.assertIn("[[bm-gated]]", marker)self.assertNotIn("not this", marker)self.assertIn("[[bm-gated]]", (self.dir / "ssn.txt").read_text())self.assertEqual(sorted(self.report()["redacted"]), ["marker.md", "ssn.txt"])def test_txt_files_are_scanned(self):run(self.gate("remove"))self.assertNotIn("ssn.txt", self.names())def test_undecodable_file_is_pulled_not_crashed_on(self):code, _ = run(self.gate("remove"))self.assertEqual(code, 0)self.assertNotIn("binary.md", self.names())self.assertIn("binary.md (unreadable, fail-closed)", self.report()["removed"])def test_unknown_mode_refuses(self):code, _ = run(self.gate("remvoe"))self.assertEqual(code, 2)self.assertIn("flagged.md", self.names()) # nothing touchedself.assertFalse((self.dir / "gate-report.json").exists())def test_placeholder_path_refuses(self):mod = load("content_gate.py", {"BM_STAGING_DIR": "/Users/CHANGEME/cowork-staging/staging","BM_GATE_MODE": "remove"})code, _ = run(mod)self.assertEqual(code, 2)if __name__ == "__main__":unittest.main()