import subprocess import sys import tempfile import unittest from pathlib import Path ROOT = Path(__file__).resolve().parents[2] CHECKER = ROOT / "scripts" / "check-community-scope.py" class CommunityScopeCheckTests(unittest.TestCase): def run_checker(self, root: Path, files: list[str]) -> subprocess.CompletedProcess[str]: return subprocess.run( [sys.executable, str(CHECKER), "--root", str(root), "--files", *files], check=False, text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) def test_passes_for_clean_community_content(self) -> None: with tempfile.TemporaryDirectory() as tmp: root = Path(tmp) (root / "README.md").write_text( "Crank publishes REST API endpoints as MCP tools.\n", encoding="utf-8", ) result = self.run_checker(root, ["README.md"]) self.assertEqual(result.returncode, 0, result.stderr) self.assertIn("Community scope check passed", result.stdout) def test_fails_for_forbidden_product_marker(self) -> None: with tempfile.TemporaryDirectory() as tmp: root = Path(tmp) (root / "apps").mkdir() (root / "apps" / "ui.md").write_text( "Hidden GraphQL protocol card must not be here.\n", encoding="utf-8", ) result = self.run_checker(root, ["apps/ui.md"]) self.assertNotEqual(result.returncode, 0) self.assertIn("apps/ui.md:1", result.stderr) self.assertIn("graphql", result.stderr.lower()) def test_ignores_default_excluded_paths(self) -> None: with tempfile.TemporaryDirectory() as tmp: root = Path(tmp) (root / "LICENSE").write_text( "The license text may mention commercial distribution terms.\n", encoding="utf-8", ) result = self.run_checker(root, ["LICENSE"]) self.assertEqual(result.returncode, 0, result.stderr) def test_skips_binary_files(self) -> None: with tempfile.TemporaryDirectory() as tmp: root = Path(tmp) (root / "logo.png").write_bytes(b"\x89PNG\x00enterprise\x00") result = self.run_checker(root, ["logo.png"]) self.assertEqual(result.returncode, 0, result.stderr) if __name__ == "__main__": unittest.main()