# [DEF:backend.tests.services.clean_release.test_report_builder:Module] # @TIER: STANDARD # @SEMANTICS: tests, clean-release, report-builder, counters # @PURPOSE: Validate compliance report builder counter integrity and blocked-run constraints. # @LAYER: Domain # @RELATION: TESTS -> backend.src.services.clean_release.report_builder # @INVARIANT: blocked run requires at least one blocking violation. from datetime import datetime, timezone import pytest from src.models.clean_release import ( CheckFinalStatus, ComplianceCheckRun, ComplianceViolation, ExecutionMode, ViolationCategory, ViolationSeverity, ) from src.services.clean_release.report_builder import ComplianceReportBuilder from src.services.clean_release.repository import CleanReleaseRepository # [DEF:_terminal_run:Function] # @PURPOSE: Build terminal/non-terminal run fixtures for report builder tests. def _terminal_run(status: CheckFinalStatus) -> ComplianceCheckRun: return ComplianceCheckRun( check_run_id="check-1", candidate_id="2026.03.03-rc1", policy_id="policy-enterprise-clean-v1", started_at=datetime.now(timezone.utc), finished_at=datetime.now(timezone.utc), final_status=status, triggered_by="tester", execution_mode=ExecutionMode.TUI, checks=[], ) # [/DEF:_terminal_run:Function] # [DEF:_blocking_violation:Function] # @PURPOSE: Build a blocking violation fixture for blocked report scenarios. def _blocking_violation() -> ComplianceViolation: return ComplianceViolation( violation_id="viol-1", check_run_id="check-1", category=ViolationCategory.EXTERNAL_SOURCE, severity=ViolationSeverity.CRITICAL, location="pypi.org", remediation="replace", blocked_release=True, detected_at=datetime.now(timezone.utc), ) # [/DEF:_blocking_violation:Function] # [DEF:test_report_builder_blocked_requires_blocking_violations:Function] # @PURPOSE: Verify BLOCKED run requires at least one blocking violation. def test_report_builder_blocked_requires_blocking_violations(): builder = ComplianceReportBuilder(CleanReleaseRepository()) run = _terminal_run(CheckFinalStatus.BLOCKED) with pytest.raises(ValueError): builder.build_report_payload(run, []) # [/DEF:test_report_builder_blocked_requires_blocking_violations:Function] # [DEF:test_report_builder_counter_consistency:Function] # @PURPOSE: Verify violations counters remain consistent for blocking payload. def test_report_builder_counter_consistency(): builder = ComplianceReportBuilder(CleanReleaseRepository()) run = _terminal_run(CheckFinalStatus.BLOCKED) report = builder.build_report_payload(run, [_blocking_violation()]) assert report.violations_count == 1 assert report.blocking_violations_count == 1 # [/DEF:test_report_builder_counter_consistency:Function] # [DEF:test_missing_operator_summary:Function] # @PURPOSE: Validate non-terminal run prevents operator summary/report generation. def test_missing_operator_summary(): builder = ComplianceReportBuilder(CleanReleaseRepository()) run = _terminal_run(CheckFinalStatus.RUNNING) with pytest.raises(ValueError) as exc: builder.build_report_payload(run, []) assert "Cannot build report for non-terminal run" in str(exc.value) # [/DEF:test_missing_operator_summary:Function] # [/DEF:backend.tests.services.clean_release.test_report_builder:Module]