← Files Marketing CouncilARCHIVED FILE

tests/test_distribution.py

11.2 KB · Oct 2, 2026 · 00:31 UTC

↓ Download file

import importlib.util
import json
import re
import shutil
import subprocess
import sys
import tempfile
import unittest
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]


def simple_frontmatter(path: Path) -> dict:
    text = path.read_text(encoding="utf-8")
    if not text.startswith("---\n"):
        return {}
    _, block, _ = text.split("---", 2)
    out = {}
    for line in block.splitlines():
        if not line.strip() or line.startswith(" ") or ":" not in line:
            continue
        key, value = line.split(":", 1)
        out[key.strip()] = value.strip().strip('"')
    return out


class DistributionTests(unittest.TestCase):
    def host_builder_module(self):
        scripts = str(ROOT / "scripts")
        sys.path.insert(0, scripts)
        try:
            path = ROOT / "scripts" / "build_host_packages.py"
            spec = importlib.util.spec_from_file_location("host_package_builder_under_test", path)
            module = importlib.util.module_from_spec(spec)
            spec.loader.exec_module(module)
            return module
        finally:
            sys.path.remove(scripts)

    def test_release_version_is_1_5_0(self):
        manifest = json.loads((ROOT / "manifest.json").read_text(encoding="utf-8"))
        self.assertEqual(manifest["version"], "1.5.0")

    def test_skill_frontmatter_uses_only_openai_supported_fields(self):
        for skill in sorted((ROOT / "skills").glob("*/SKILL.md")):
            fm = simple_frontmatter(skill)
            self.assertEqual(set(fm), {"name", "description"}, skill)

    def test_openai_plugin_manifest(self):
        path = ROOT / ".codex-plugin" / "plugin.json"
        self.assertTrue(path.exists(), path)
        data = json.loads(path.read_text(encoding="utf-8"))
        self.assertEqual(data["name"], "marketing-council")
        self.assertEqual(data["version"], "1.5.0")
        self.assertEqual(data["skills"], "./skills/")
        self.assertEqual(data["repository"], "https://github.com/imMamdouhaboammar/marketing-council-pack")
        self.assertLessEqual(len(data["interface"]["displayName"]), 30)
        self.assertLessEqual(len(data["interface"]["shortDescription"]), 30)
        self.assertLessEqual(len(data["interface"]["capabilities"]), 20)
        self.assertLessEqual(len(data["interface"]["defaultPrompt"]), 3)
        for prompt in data["interface"]["defaultPrompt"]:
            self.assertLessEqual(len(prompt), 128)
            self.assertNotIn("@", prompt)
        for key in ("logo", "composerIcon"):
            asset = ROOT / data["interface"][key].removeprefix("./")
            self.assertTrue(asset.exists(), asset)

    def test_openai_repo_marketplace(self):
        path = ROOT / ".agents" / "plugins" / "marketplace.json"
        self.assertTrue(path.exists(), path)
        data = json.loads(path.read_text(encoding="utf-8"))
        self.assertEqual(data["plugins"][0]["name"], "marketing-council")
        self.assertEqual(data["plugins"][0]["source"]["source"], "url")
        self.assertIn("marketing-council-pack", data["plugins"][0]["source"]["url"])

    def test_every_skill_has_compliant_openai_interface_metadata(self):
        skills = sorted((ROOT / "skills").glob("*/SKILL.md"))
        self.assertEqual(len(skills), 29)
        for skill in skills:
            slug = skill.parent.name
            metadata = skill.parent / "agents" / "openai.yaml"
            self.assertTrue(metadata.exists(), metadata)
            text = metadata.read_text(encoding="utf-8")
            self.assertIn("interface:", text)

            values = {}
            for line in text.splitlines():
                stripped = line.strip()
                if stripped.startswith(("display_name:", "short_description:", "default_prompt:")):
                    key, value = stripped.split(":", 1)
                    values[key] = value.strip().strip('"')

            self.assertTrue(values.get("display_name"), metadata)
            short = values.get("short_description", "")
            self.assertGreaterEqual(len(short), 25, metadata)
            self.assertLessEqual(len(short), 64, metadata)
            prompt = values.get("default_prompt", "")
            self.assertIn(f"${slug}", prompt, metadata)
            self.assertNotIn("\n", prompt, metadata)

    def test_claude_plugin_and_marketplace(self):
        plugin = ROOT / ".claude-plugin" / "plugin.json"
        market = ROOT / ".claude-plugin" / "marketplace.json"
        self.assertTrue(plugin.exists(), plugin)
        self.assertTrue(market.exists(), market)
        pdata = json.loads(plugin.read_text(encoding="utf-8"))
        mdata = json.loads(market.read_text(encoding="utf-8"))
        self.assertEqual(pdata["name"], "marketing-council")
        self.assertEqual(pdata["version"], "1.5.0")
        self.assertEqual(pdata["skills"], "./skills/")
        self.assertEqual(pdata["agents"], "./agents/")
        self.assertEqual(mdata["name"], "marketing-council")
        self.assertEqual(mdata["plugins"][0]["name"], "marketing-council")
        self.assertEqual(mdata["plugins"][0]["source"]["source"], "github")
        self.assertEqual(mdata["plugins"][0]["source"]["repo"], "imMamdouhaboammar/marketing-council-pack")

    def test_all_role_docs_are_valid_claude_agents(self):
        agents = sorted((ROOT / "agents").glob("*.md"))
        self.assertEqual(len(agents), 24)
        for path in agents:
            fm = simple_frontmatter(path)
            self.assertEqual(fm.get("name"), path.stem, path)
            self.assertTrue(fm.get("description", "").startswith("Use when"), path)

    def test_readme_contains_verified_install_surfaces(self):
        text = (ROOT / "README.md").read_text(encoding="utf-8")
        required = [
            "npx skills add imMamdouhaboammar/marketing-council-pack --all -y",
            "-a codex",
            "-a claude-code",
            "codex plugin marketplace add imMamdouhaboammar/marketing-council-pack",
            "/plugin marketplace add imMamdouhaboammar/marketing-council-pack",
            "/plugin install marketing-council@marketing-council",
        ]
        for item in required:
            self.assertIn(item, text)

    def test_host_package_primitives_reject_symlink_sources(self):
        module = self.host_builder_module()
        with tempfile.TemporaryDirectory() as td:
            root = Path(td)
            outside = root / "outside.txt"
            outside.write_text("must not be packaged", encoding="utf-8")

            source = root / "source"
            source.mkdir()
            (source / "leak.txt").symlink_to(outside)
            with self.assertRaises(ValueError):
                module.copy_tree_clean(source, root / "copy")
            with self.assertRaises(ValueError):
                module.deterministic_zip(source, root / "archive.zip")

    def test_host_package_builder_outputs_expected_archives(self):
        script = ROOT / "scripts" / "build_host_packages.py"
        self.assertTrue(script.exists(), script)
        with tempfile.TemporaryDirectory() as td:
            subprocess.run([sys.executable, str(script), "--output-root", td], check=True)
            out = Path(td)
            expected = {
                "marketing-council-openai-plugin-v1.5.0.zip",
                "marketing-council-claude-marketplace-v1.5.0.zip",
                "marketing-council-skill-v1.5.0.zip",
            }
            self.assertTrue(expected.issubset({p.name for p in out.glob("*.zip")}))

    def test_host_packages_are_complete_and_deterministic(self):
        import hashlib
        import zipfile

        script = ROOT / "scripts" / "build_host_packages.py"
        self.assertTrue(script.exists(), script)
        with tempfile.TemporaryDirectory() as a, tempfile.TemporaryDirectory() as b:
            subprocess.run([sys.executable, str(script), "--output-root", a], check=True)
            subprocess.run([sys.executable, str(script), "--output-root", b], check=True)

            names = [
                "marketing-council-openai-plugin-v1.5.0.zip",
                "marketing-council-claude-marketplace-v1.5.0.zip",
                "marketing-council-skill-v1.5.0.zip",
            ]
            for name in names:
                one = Path(a) / name
                two = Path(b) / name
                self.assertEqual(hashlib.sha256(one.read_bytes()).hexdigest(), hashlib.sha256(two.read_bytes()).hexdigest(), name)

            with zipfile.ZipFile(Path(a) / names[0]) as zf:
                entries = set(zf.namelist())
                self.assertIn(".codex-plugin/plugin.json", entries)
                self.assertIn("agents/marketing-skeptic.md", entries)
                self.assertEqual(sum(1 for e in entries if e.startswith("skills/") and e.endswith("/SKILL.md")), 29)
                self.assertIn("routing/skill-routes.json", entries)
                self.assertIn("scripts/skill_router.py", entries)

            with zipfile.ZipFile(Path(a) / names[1]) as zf:
                entries = set(zf.namelist())
                self.assertIn(".claude-plugin/marketplace.json", entries)
                prefix = "plugins/marketing-council/"
                self.assertIn(prefix + ".claude-plugin/plugin.json", entries)
                self.assertEqual(sum(1 for e in entries if e.startswith(prefix + "skills/") and e.endswith("/SKILL.md")), 29)
                self.assertEqual(sum(1 for e in entries if e.startswith(prefix + "agents/") and e.endswith(".md")), 24)

            with zipfile.ZipFile(Path(a) / names[2]) as zf:
                entries = set(zf.namelist())
                self.assertIn("marketing-council/SKILL.md", entries)
                self.assertIn("marketing-council/agents/marketing-skeptic.md", entries)

    def test_distribution_validator_exists_and_accepts_source(self):
        script = ROOT / "scripts" / "validate_distribution.py"
        self.assertTrue(script.exists(), script)
        result = subprocess.run([sys.executable, str(script), str(ROOT), "--json"], text=True, capture_output=True)
        self.assertEqual(result.returncode, 0, result.stdout + result.stderr)
        payload = json.loads(result.stdout)
        self.assertTrue(payload["valid"], payload)
        self.assertEqual(payload["skill_count"], 29)
        self.assertEqual(payload["agent_count"], 24)

    def test_openai_public_validator_accepts_built_plugin(self):
        import zipfile

        builder = ROOT / "scripts" / "build_host_packages.py"
        validator = ROOT / "scripts" / "validate_openai_plugin.py"
        self.assertTrue(validator.exists(), validator)
        with tempfile.TemporaryDirectory() as td:
            subprocess.run([sys.executable, str(builder), "--output-root", td], check=True, stdout=subprocess.DEVNULL)
            archive = Path(td) / "marketing-council-openai-plugin-v1.5.0.zip"
            extracted = Path(td) / "plugin"
            with zipfile.ZipFile(archive) as zf:
                zf.extractall(extracted)
            result = subprocess.run([sys.executable, str(validator), str(extracted), "--json"], text=True, capture_output=True)
            self.assertEqual(result.returncode, 0, result.stdout + result.stderr)
            payload = json.loads(result.stdout)
            self.assertTrue(payload["ok"], payload)
            self.assertEqual(payload["architecture"], "skills-only")
            self.assertEqual(len(payload["skills"]), 29)


if __name__ == "__main__":
    unittest.main()

SHA-256: d5707a5d853f2246bf8c1de3e280a8c9236dc7351e73c73a13976a8bc4b62d90