# -*- coding: utf-8 -*- """Tests for full modernization governance gate runner.""" from __future__ import annotations import importlib.util import json import subprocess import sys from pathlib import Path ROOT = Path(__file__).resolve().parents[1] SCRIPT = ROOT / "scripts" / "check_full_modernization_gates.py" REPORT = ROOT / "docs" / "migration" / "full-modernization-architecture-blueprint" / "quality_gate_report.json" SCOPE_MATRIX = ROOT / "docs" / "migration" / "full-modernization-architecture-blueprint" / "route_scope_matrix.json" _GATES_SPEC = importlib.util.spec_from_file_location("check_full_modernization_gates", SCRIPT) assert _GATES_SPEC and _GATES_SPEC.loader gates = importlib.util.module_from_spec(_GATES_SPEC) sys.modules[_GATES_SPEC.name] = gates _GATES_SPEC.loader.exec_module(gates) def _run(mode: str) -> subprocess.CompletedProcess[str]: return subprocess.run( ["python", str(SCRIPT), "--mode", mode, "--report", str(REPORT)], cwd=str(ROOT), capture_output=True, text=True, check=False, ) def test_gate_runner_warn_mode_passes_and_generates_report(): result = _run("warn") assert result.returncode == 0, result.stdout + result.stderr payload = json.loads(REPORT.read_text(encoding="utf-8")) assert payload["mode"] == "warn" assert payload["passed"] is True def test_gate_runner_block_mode_passes_current_baseline(): result = _run("block") assert result.returncode == 0, result.stdout + result.stderr payload = json.loads(REPORT.read_text(encoding="utf-8")) assert payload["mode"] == "block" assert payload["passed"] is True def test_scope_matrix_has_all_routes_promoted_to_in_scope(): matrix = json.loads(SCOPE_MATRIX.read_text(encoding="utf-8")) deferred = {item["route"] for item in matrix["deferred"]} assert deferred == set(), "all deferred routes should be promoted to in-scope" in_scope_routes = {item["route"] for item in matrix["in_scope"]} for route in ("/tables", "/excel-query", "/query-tool", "/mid-section-defect"): assert route in in_scope_routes, f"{route} should be in-scope" def test_route_contract_parity_check_detects_route_set_drift(): report = gates.CheckReport(mode="block") backend = {"/wip-overview": {"scope": "in-scope"}} frontend = { "/wip-overview": "in-scope", "/extra": "deferred", } gates._check_frontend_backend_route_contract_parity(backend, frontend, report) assert any("/extra" in error for error in report.errors) def test_route_contract_parity_check_detects_scope_mismatch(): report = gates.CheckReport(mode="block") backend = {"/wip-overview": {"scope": "in-scope"}} frontend = {"/wip-overview": "deferred"} gates._check_frontend_backend_route_contract_parity(backend, frontend, report) assert any("scope mismatch" in error for error in report.errors) def test_style_governance_flags_shell_tokens_without_fallback(tmp_path): report = gates.CheckReport(mode="block") css_file = tmp_path / "route.css" css_file.write_text( ".demo { background: linear-gradient(var(--portal-brand-start), #fff); }", encoding="utf-8", ) original_route_css_targets = gates._route_css_targets try: gates._route_css_targets = lambda: {"/wip-overview": [css_file]} # type: ignore[assignment] gates._check_style_governance({"/wip-overview"}, {}, report) finally: gates._route_css_targets = original_route_css_targets # type: ignore[assignment] assert any("without fallback" in error for error in report.errors)