"""Tests for the Regulatory Optimization renderer (Roadmap / Management view of the Capability Delta). Acceptance: rank measures by regulatory leverage (most regulatory requirements closed at once), report the compression (identified requirements -> measures), answer the budget question, and bind to the SAME RS-005 Capability Delta the Interview Renderer uses. Percentages are over IDENTIFIED requirements (Welt-1), never "% gesetzeskonform". """ from __future__ import annotations from compliance.optimization import ( BudgetPlan, OptimizationPlan, regulatory_leverage, roadmap_from_delta, select_within_budget, ) from compliance.transition_reasoning import ( CapabilityCoverage, CoverageStatus, TransitionAssessment, TransitionSummary, ) # Illustrative leverage spread (the user's patch_management example reaches leverage 4). CAPS = { "patch_management": ["CRA", "MaschinenVO", "IEC62443", "ISO27001"], # leverage 4 "access_control": ["CRA", "ISO27001"], # leverage 2 "sbom": ["CRA"], # leverage 1 "machine_guards": ["MaschinenVO"], # leverage 1 } def test_ranked_by_leverage_desc(): plan = regulatory_leverage(CAPS) order = [m.capability_id for m in plan.ranked_measures] assert order[0] == "patch_management" # leverage 4 first assert order[1] == "access_control" # leverage 2 next assert plan.ranked_measures[0].leverage == 4 def test_compression_counts(): plan = regulatory_leverage(CAPS) # total requirements = 4 + 2 + 1 + 1 = 8 closed by 4 measures assert plan.total_requirements == 8 and plan.total_measures == 4 assert "8 identifizierte Anforderungen" in plan.headline def test_cumulative_coverage_monotone_to_one(): plan = regulatory_leverage(CAPS) cums = [m.cumulative_coverage for m in plan.ranked_measures] assert cums == sorted(cums) # non-decreasing assert abs(cums[-1] - 1.0) < 1e-9 # full set -> 100% assert plan.ranked_measures[0].cumulative_requirements == 4 def test_tie_break_deterministic_by_id(): # machine_guards vs sbom both leverage 1 -> alphabetical: machine_guards before sbom plan = regulatory_leverage(CAPS) tail = [m.capability_id for m in plan.ranked_measures if m.leverage == 1] assert tail == ["machine_guards", "sbom"] def test_budget_picks_highest_leverage(): b = select_within_budget(CAPS, 2) assert b.selected_capabilities == ["patch_management", "access_control"] assert b.requirements_closed == 6 and b.total_requirements == 8 assert abs(b.coverage_ratio - 0.75) < 1e-9 assert "6 von 8" in b.headline and "75%" in b.headline def test_budget_over_and_zero(): assert select_within_budget(CAPS, 99).requirements_closed == 8 # capped at all z = select_within_budget(CAPS, 0) assert z.selected_capabilities == [] and z.requirements_closed == 0 def test_in_scope_filter(): # restrict to CRA + MaschinenVO: patch=2, access=1(CRA), sbom=1, guards=1 -> total 5 plan = regulatory_leverage(CAPS, in_scope=["CRA", "MaschinenVO"]) assert plan.total_requirements == 5 assert plan.ranked_measures[0].capability_id == "patch_management" assert plan.ranked_measures[0].leverage == 2 # only CRA+MaschinenVO counted def test_deterministic(): a, b = regulatory_leverage(CAPS), regulatory_leverage(CAPS) assert [m.capability_id for m in a.ranked_measures] == [m.capability_id for m in b.ranked_measures] assert a.headline == b.headline def test_empty(): plan = regulatory_leverage({}) assert plan.total_requirements == 0 and plan.ranked_measures == [] assert isinstance(plan, OptimizationPlan) def test_capability_with_no_in_scope_requirement_dropped(): plan = regulatory_leverage({"x": ["CRA"], "y": ["DataAct"]}, in_scope=["CRA"]) assert [m.capability_id for m in plan.ranked_measures] == ["x"] # y covers nothing in scope # The keystone: optimization renders the SAME RS-005 delta the interview uses. def _delta(): return TransitionAssessment( target_id="CRA+MaschinenVO", coverage=[ CapabilityCoverage(capability_id="patch_management", status=CoverageStatus.MISSING), CapabilityCoverage(capability_id="sbom", status=CoverageStatus.MISSING), CapabilityCoverage(capability_id="access_control", status=CoverageStatus.ALREADY_COVERED), CapabilityCoverage(capability_id="machine_guards", status=CoverageStatus.MISSING), ], summary=TransitionSummary(), ) def test_roadmap_from_delta_uses_only_open_capabilities(): plan = roadmap_from_delta(_delta(), CAPS) ids = [m.capability_id for m in plan.ranked_measures] assert "access_control" not in ids # ALREADY_COVERED is not an open measure assert ids == ["patch_management", "machine_guards", "sbom"] # MISSING ranked by leverage assert isinstance(plan, OptimizationPlan) def test_roadmap_from_delta_honours_status_filter(): # include NEEDS_CONFIRMATION too -> still only those present in CAPS contribute requirements a = _delta() a.coverage.append(CapabilityCoverage(capability_id="access_control", status=CoverageStatus.NEEDS_CONFIRMATION)) plan = roadmap_from_delta(a, CAPS, open_statuses=[CoverageStatus.MISSING, CoverageStatus.NEEDS_CONFIRMATION]) assert "access_control" in [m.capability_id for m in plan.ranked_measures] def test_budget_returns_budgetplan_type(): assert isinstance(select_within_budget(CAPS, 1), BudgetPlan)