"""Compatibility accounting tests.""" from datetime import UTC, datetime from pathlib import Path from typing import cast import pytest from pydantic import SecretStr from app.compatibility import ( CompatibilityDimension, EvidenceManifest, build_report, resolve_evidence_path, ) from app.config import Settings from app.contracts.model import Method, PathContract, Schema, Snapshot from app.contracts.runtime import build_compatibility_for_snapshot from app.handlers.core import build_core_handlers pytestmark = pytest.mark.pve_stub def snapshot() -> Snapshot: methods = ( Method( verb="GET", name="version", returns=Schema(type="object"), checksum="1" * 64, ), Method( verb="POST", name="update", returns=Schema(type="null"), checksum="2" * 64, ), ) return Snapshot( source_version="9.2.3", retrieved_at=datetime(2026, 1, 1, tzinfo=UTC), raw_sha256="0" * 64, paths=(PathContract(path="/nodes/{node}", methods=methods),), path_count=1, method_count=2, ) def test_report_scores_levels_and_groups_independently() -> None: report = build_report( snapshot(), implemented=frozenset({("/nodes/{node}", "GET")}), observed=frozenset({("/nodes/{node}", "GET"), ("/nodes/{node}", "POST")}), verified=frozenset({("/nodes/{node}", "GET")}), ) data = report.as_json() assert data["total_declared"] == 2 levels = data["levels"] assert isinstance(levels, dict) assert levels["implemented"]["score"] == 0.5 assert levels["observed"]["score"] == 1.0 assert data["groups"] == {"nodes": {"declared": 2, "implemented": 1, "verified": 1}} assert "| implemented | 1 | 50.00% |" in report.as_markdown() def test_report_rejects_unbound_evidence() -> None: with pytest.raises(ValueError, match="undeclared"): build_report(snapshot(), verified=frozenset({("/missing", "GET")})) def test_all_thirteen_dimensions_have_independent_evidence_and_renderers() -> None: method = frozenset({("/nodes/{node}", "GET")}) report = build_report( snapshot(), implemented=method, dimensions={dimension: method for dimension in CompatibilityDimension}, ) payload = report.as_json() dimensions = cast(dict[str, dict[str, object]], payload["dimensions"]) assert list(dimensions) == [dimension.value for dimension in CompatibilityDimension] assert len(dimensions) == 13 assert all(item["count"] == 1 for item in dimensions.values()) assert payload["dimension_groups"] classifications = cast(dict[str, list[str]], payload["classifications"]) assert classifications["fully_compatible"] == ["GET /nodes/{node}"] assert not classifications["partially_compatible"] assert "| permissions | 1 |" in report.as_markdown() assert "long_task_behavior1" in report.as_html() assert report.canonical_json() == report.canonical_json() def test_dimension_evidence_must_reference_declared_method() -> None: with pytest.raises(ValueError, match="permissions evidence"): build_report( snapshot(), dimensions={CompatibilityDimension.PERMISSIONS: frozenset({("/missing", "GET")})}, ) def test_evidence_manifest_requires_provenance_and_unique_methods() -> None: manifest = EvidenceManifest.model_validate( { "profile": "pve-9.2", "source_version": "9.2.3", "records": [ { "path": "/nodes/{node}", "verb": "GET", "dimensions": ["http_status", "json_structure"], "sources": ["tests/compatibility/test_proxmoxer.py"], } ], } ) evidence = manifest.dimension_map() assert evidence[CompatibilityDimension.HTTP_STATUS] == frozenset({("/nodes/{node}", "GET")}) assert not evidence[CompatibilityDimension.PERMISSIONS] assert manifest.verified_methods() == frozenset({("/nodes/{node}", "GET")}) assert manifest.observed_methods() == frozenset({("/nodes/{node}", "GET")}) duplicate = manifest.model_dump(mode="json") duplicate["records"].append(duplicate["records"][0]) with pytest.raises(ValueError, match="duplicate methods"): EvidenceManifest.model_validate(duplicate) def test_resolve_evidence_path_prefers_per_version_ledger() -> None: settings = Settings(compatibility_evidence=Path("evidence/pve-9.2.3.json")) assert resolve_evidence_path("7.4-16", settings) == Path("evidence/pve-7.4-16.json").resolve() assert resolve_evidence_path("9.2.3", settings) == Path("evidence/pve-9.2.3.json").resolve() def test_build_compatibility_wires_verified_from_version_ledger() -> None: snapshot = Snapshot.model_validate_json( Path( "contracts/e61a893e996d05d376579226e7dfbedbcfce8b71787adacffbc557e6e35901c1/" "snapshot.json" ).read_bytes() ) settings = Settings( contract_snapshot=Path( "contracts/e61a893e996d05d376579226e7dfbedbcfce8b71787adacffbc557e6e35901c1/" "snapshot.json" ), compatibility_evidence=Path("evidence/pve-9.2.3.json"), ticket_signing_key=SecretStr("x" * 32), ) handlers = build_core_handlers(settings) report = build_compatibility_for_snapshot(snapshot, handlers, settings) data = report.as_json() levels = cast(dict[str, dict[str, object]], data["levels"]) assert levels["verified"]["count"] == data["total_declared"] assert levels["observed"]["count"] == data["total_declared"] assert levels["implemented"]["count"] == data["total_declared"]