"""Tests for compliance domain entities.""" import pytest from app.domain.entities.compliance import ( ComplianceControlEntity, ComplianceFrameworkEntity, ControlCoverageStatus, ) # ── Control coverage status ─────────────────────────────────────────────── def test_control_all_techniques_validated_covered(): """All techniques validated → covered.""" control = ComplianceControlEntity( control_id="AC-2", title="Account Management", technique_statuses=["validated", "validated"], ) assert control.coverage_status == ControlCoverageStatus.covered def test_control_all_techniques_partial_covered(): """All techniques partial → covered.""" control = ComplianceControlEntity( control_id="AC-2", title="Account Management", technique_statuses=["partial"], ) assert control.coverage_status == ControlCoverageStatus.covered def test_control_mixed_statuses_partially_covered(): """Mixed statuses (some validated/partial, some not) → partially_covered.""" control = ComplianceControlEntity( control_id="AC-2", title="Account Management", technique_statuses=["validated", "not_evaluated"], ) assert control.coverage_status == ControlCoverageStatus.partially_covered def test_control_no_validated_techniques_not_covered(): """No validated/partial techniques → not_covered.""" control = ComplianceControlEntity( control_id="AC-2", title="Account Management", technique_statuses=["not_evaluated", "not_covered"], ) assert control.coverage_status == ControlCoverageStatus.not_covered def test_control_empty_techniques_not_covered(): """Empty technique_statuses → not_covered.""" control = ComplianceControlEntity( control_id="AC-2", title="Account Management", technique_statuses=[], ) assert control.coverage_status == ControlCoverageStatus.not_covered # ── Framework coverage ───────────────────────────────────────────────────── def test_framework_coverage_pct_calculation(): """Framework coverage_pct = (covered_controls / total_controls) * 100.""" controls = [ ComplianceControlEntity("AC-1", "Title 1", technique_statuses=["validated"]), ComplianceControlEntity("AC-2", "Title 2", technique_statuses=["not_evaluated"]), ComplianceControlEntity("AC-3", "Title 3", technique_statuses=["validated", "partial"]), ComplianceControlEntity("AC-4", "Title 4", technique_statuses=["partial"]), ComplianceControlEntity("AC-5", "Title 5", technique_statuses=[]), ] framework = ComplianceFrameworkEntity(name="NIST 800-53", controls=controls) # AC-1: covered, AC-2: not_covered, AC-3: covered, AC-4: covered, AC-5: not_covered assert framework.total_controls == 5 assert framework.covered_controls == 3 assert framework.coverage_pct == 60.0 def test_framework_get_gap_controls(): """get_gap_controls returns only uncovered and partially_covered controls.""" controls = [ ComplianceControlEntity("AC-1", "Covered", technique_statuses=["validated"]), ComplianceControlEntity("AC-2", "Partial", technique_statuses=["validated", "not_evaluated"]), ComplianceControlEntity("AC-3", "Not Covered", technique_statuses=["not_evaluated"]), ComplianceControlEntity("AC-4", "Empty", technique_statuses=[]), ] framework = ComplianceFrameworkEntity(name="Test", controls=controls) gaps = framework.get_gap_controls() assert len(gaps) == 3 assert gaps[0].control_id == "AC-2" assert gaps[1].control_id == "AC-3" assert gaps[2].control_id == "AC-4" def test_framework_no_controls_coverage_pct_zero(): """Framework with no controls → coverage_pct is 0.""" framework = ComplianceFrameworkEntity(name="Empty", controls=[]) assert framework.total_controls == 0 assert framework.covered_controls == 0 assert framework.coverage_pct == 0.0