"""Tests for the Implementation Playbook renderer (the Berater view, "wie komme ich dort hin?"). Acceptance: for one capability, assemble the journey (why / closes-which-regulations / tools / process / evidence / controls) from curated knowledge + leverage + injected Execution links; chain the Optimization Roadmap into per-measure playbooks; surface capabilities without content as honest `missing` stubs. Curated content is an expert draft, never normative. """ from __future__ import annotations from compliance.optimization import regulatory_leverage from compliance.playbook import Playbook, build_playbook, playbooks_for_plan SBOM = { "title": "SBOM aufbauen", "why": "CRA verlangt ein Komponenten-Inventar.", "tools": ["CycloneDX", "Syft"], "process_steps": [{"title": "Format wählen", "detail": "CycloneDX"}, {"title": "In CI erzeugen", "detail": ""}], "expected_evidence": ["sbom_per_release"], "how_others_do_it": "CI + Dependency-Track.", "status": "draft", } def test_build_playbook_full_journey(): pb = build_playbook("sbom_creation", SBOM, closes_regulations=["CRA", "MaschinenVO"], control_links=["component_inventory"]) assert pb.title == "SBOM aufbauen" and pb.status == "draft" assert pb.closes_regulations == ["CRA", "MaschinenVO"] and pb.leverage == 2 assert pb.tools == ["CycloneDX", "Syft"] assert [s.order for s in pb.process_steps] == [1, 2] assert pb.process_steps[0].title == "Format wählen" assert pb.expected_evidence == ["sbom_per_release"] assert pb.controls == ["component_inventory"] # injected from Execution assert pb.disclaimer # always carries the expert-draft caveat def test_missing_knowledge_is_honest_stub(): pb = build_playbook("product_cyber_risk_assessment", None, closes_regulations=["CRA", "MaschinenVO"]) assert pb.status == "missing" # the content-owed signal assert pb.leverage == 2 and pb.closes_regulations == ["CRA", "MaschinenVO"] # leverage still known assert pb.tools == [] and pb.process_steps == [] assert "Knowledge Acquisition" in pb.why def test_closes_regulations_deduped_and_sorted(): pb = build_playbook("x", SBOM, closes_regulations=["MaschinenVO", "CRA", "CRA"]) assert pb.closes_regulations == ["CRA", "MaschinenVO"] and pb.leverage == 2 def test_controls_default_empty_no_execution_data(): pb = build_playbook("x", SBOM, closes_regulations=["CRA"]) assert pb.controls == [] # no Execution data unless injected def test_playbooks_for_plan_orders_by_leverage_and_stubs_missing(): caps = {"sbom_creation": ["CRA"], "pcra": ["CRA", "MaschinenVO"], "guards": ["MaschinenVO"]} plan = regulatory_leverage(caps) pbs = playbooks_for_plan(plan, {"sbom_creation": SBOM}, top_k=3) assert [p.capability_id for p in pbs][0] == "pcra" # highest leverage first by = {p.capability_id: p for p in pbs} assert by["pcra"].status == "missing" and by["pcra"].leverage == 2 assert by["sbom_creation"].status == "draft" # has content assert by["guards"].status == "missing" def test_playbooks_for_plan_top_k_and_injected_controls(): caps = {"a": ["CRA", "MaschinenVO"], "b": ["CRA"], "c": ["CRA"]} plan = regulatory_leverage(caps) pbs = playbooks_for_plan(plan, {}, top_k=1, control_links_by_cap={"a": ["ctrl_1"]}) assert len(pbs) == 1 and pbs[0].capability_id == "a" assert pbs[0].controls == ["ctrl_1"] def test_playbooks_for_plan_empty(): plan = regulatory_leverage({}) assert playbooks_for_plan(plan, {}) == [] def test_deterministic(): caps = {"a": ["CRA", "MaschinenVO"], "b": ["CRA"]} plan = regulatory_leverage(caps) a = [p.capability_id for p in playbooks_for_plan(plan, {})] b = [p.capability_id for p in playbooks_for_plan(plan, {})] assert a == b def test_returns_playbook_type(): assert isinstance(build_playbook("x", None), Playbook)