# [DEF:backend.tests.api.routes.test_clean_release_api:Module] # @TIER: STANDARD # @SEMANTICS: tests, api, clean-release, checks, reports # @PURPOSE: Contract tests for clean release checks and reports endpoints. # @LAYER: Domain # @RELATION: TESTS -> backend.src.api.routes.clean_release # @INVARIANT: API returns deterministic payload shapes for checks and reports. from datetime import datetime, timezone from fastapi.testclient import TestClient from src.app import app from src.dependencies import get_clean_release_repository from src.models.clean_release import ( CleanProfilePolicy, ProfileType, ReleaseCandidate, ReleaseCandidateStatus, ResourceSourceEntry, ResourceSourceRegistry, ) from src.services.clean_release.repository import CleanReleaseRepository def _repo_with_seed_data() -> CleanReleaseRepository: repo = CleanReleaseRepository() repo.save_candidate( ReleaseCandidate( candidate_id="2026.03.03-rc1", version="2026.03.03", profile=ProfileType.ENTERPRISE_CLEAN, created_at=datetime.now(timezone.utc), created_by="tester", source_snapshot_ref="git:abc123", status=ReleaseCandidateStatus.PREPARED, ) ) repo.save_registry( ResourceSourceRegistry( registry_id="registry-internal-v1", name="Internal", entries=[ ResourceSourceEntry( source_id="src-1", host="repo.intra.company.local", protocol="https", purpose="artifact-repo", enabled=True, ) ], updated_at=datetime.now(timezone.utc), updated_by="tester", status="active", ) ) repo.save_policy( CleanProfilePolicy( policy_id="policy-enterprise-clean-v1", policy_version="1.0.0", active=True, prohibited_artifact_categories=["test-data"], required_system_categories=["system-init"], external_source_forbidden=True, internal_source_registry_ref="registry-internal-v1", effective_from=datetime.now(timezone.utc), profile=ProfileType.ENTERPRISE_CLEAN, ) ) return repo def test_start_check_and_get_status_contract(): repo = _repo_with_seed_data() app.dependency_overrides[get_clean_release_repository] = lambda: repo try: client = TestClient(app) start = client.post( "/api/clean-release/checks", json={ "candidate_id": "2026.03.03-rc1", "profile": "enterprise-clean", "execution_mode": "tui", "triggered_by": "tester", }, ) assert start.status_code == 202 payload = start.json() assert set(["check_run_id", "candidate_id", "status", "started_at"]).issubset(payload.keys()) check_run_id = payload["check_run_id"] status_resp = client.get(f"/api/clean-release/checks/{check_run_id}") assert status_resp.status_code == 200 status_payload = status_resp.json() assert status_payload["check_run_id"] == check_run_id assert "final_status" in status_payload assert "checks" in status_payload finally: app.dependency_overrides.clear() def test_get_report_not_found_returns_404(): repo = _repo_with_seed_data() app.dependency_overrides[get_clean_release_repository] = lambda: repo try: client = TestClient(app) resp = client.get("/api/clean-release/reports/unknown-report") assert resp.status_code == 404 finally: app.dependency_overrides.clear()