from __future__ import annotations import ast import importlib.util import json from pathlib import Path import tempfile import unittest SCRIPT = ( Path(__file__).resolve().parents[1] / "tools" / "inventory" / "platform-interface-inventory.py" ) SPEC = importlib.util.spec_from_file_location("platform_interface_inventory", SCRIPT) assert SPEC is not None and SPEC.loader is not None inventory = importlib.util.module_from_spec(SPEC) SPEC.loader.exec_module(inventory) class PlatformInterfaceInventoryTests(unittest.TestCase): def test_workspace_resolution_prefers_populated_checkout_siblings(self) -> None: with tempfile.TemporaryDirectory() as directory: root = Path(directory) sibling = root / "checkout" meta = sibling / "govoplan" configured = root / "configured" (sibling / "govoplan-core" / "src").mkdir(parents=True) (configured / "govoplan-core").mkdir(parents=True) previous = inventory.META_ROOT inventory.META_ROOT = meta try: resolved = inventory._resolve_workspace_root( { "default_parent": str(configured), "repositories": [{"path": "govoplan-core"}], } ) finally: inventory.META_ROOT = previous self.assertEqual(sibling.resolve(), resolved) def test_canonical_api_path_normalizes_versions_and_parameters(self) -> None: self.assertEqual( inventory.canonical_api_path( "http://localhost/api/v1/campaigns/${campaignId}?limit=10" ), "/campaigns/{}", ) self.assertEqual( inventory.canonical_api_path("/api/v2/campaigns/{campaign_id}"), "/campaigns/{}", ) self.assertEqual( inventory.canonical_api_path("/api/v1/calendar/events/delta${querySuffix}"), "/calendar/events/delta", ) self.assertEqual( inventory.canonical_api_path("/api/v1/calendar/events/${eventId}"), "/calendar/events/{}", ) def test_endpoint_declarations_are_exact_and_require_missing_ui_issue(self) -> None: with tempfile.TemporaryDirectory() as directory: path = Path(directory) / "endpoints.json" path.write_text( json.dumps( { "schema_version": 1, "endpoints": [ { "repository": "govoplan-example", "method": "GET", "path": "/example/items/{}", "category": "public_integration", "rationale": "Published integration API.", } ], } ), encoding="utf-8", ) declarations = inventory._load_endpoint_declarations(path) self.assertIn( ("govoplan-example", "GET", "/example/items/{}"), declarations, ) payload = json.loads(path.read_text(encoding="utf-8")) payload["endpoints"][0]["category"] = "missing_ui" path.write_text(json.dumps(payload), encoding="utf-8") with self.assertRaisesRegex(ValueError, "tracking_issue"): inventory._load_endpoint_declarations(path) def test_bounded_workflow_read_apis_have_explicit_headless_declarations(self) -> None: declarations = inventory._load_endpoint_declarations(inventory.DEFAULT_ENDPOINT_DECLARATIONS) for path in ( "/workflow/instances/summaries", "/workflow/instances/{}/summary", "/workflow/instances/{}/steps", "/workflow/instances/{}/events", ): with self.subTest(path=path): entry = declarations[("govoplan-workflow-engine", "GET", path)] self.assertEqual("intentionally_headless", entry["category"]) self.assertIn("current-authorized", entry["rationale"]) self.assertIn("workflow.instance-history", entry["rationale"]) def test_inventory_reports_unclassified_and_stale_endpoint_declarations( self, ) -> None: webui = { "frontendApiReferences": [], "translationUsages": [], "translationCatalog": {"en": {}, "de": {}}, "fields": [], "labels": [], "visibleText": [], "routes": [], "navigation": [], "uiCapabilities": [], "dynamicTranslationUsages": [], } endpoint = { "repository": "govoplan-example", "method": "GET", "path": "/api/v1/example/items", "file": "src/example.py", "line": 1, "handler": "items", "router": "router", } stale = { "repository": "govoplan-example", "method": "GET", "path": "/example/removed", "category": "removable", "rationale": "Removal is pending.", } result = inventory._assemble_inventory( webui=webui, backend_endpoints=[endpoint], manifests=[], endpoint_declarations={ ("govoplan-example", "GET", "/example/removed"): stale, }, ) self.assertEqual(1, result["summary"]["unclassified_backend_endpoints"]) self.assertEqual(1, result["summary"]["stale_endpoint_declarations"]) self.assertIsNone(result["api"]["backend_endpoints"][0]["surface"]) def test_endpoint_only_strict_mode_does_not_fail_on_translation_debt( self, ) -> None: result = { "translation_health": {"missing_catalog_entries": ["missing.key"]}, "api": { "unclassified_endpoints": [], "stale_endpoint_declarations": [], }, } self.assertEqual( [], inventory._strict_failures( result, check_translations=False, check_endpoints=True, ), ) self.assertEqual( ["used translation keys are missing from generated catalogs"], inventory._strict_failures( result, check_translations=True, check_endpoints=True, ), ) def test_high_risk_help_baseline_is_validated(self) -> None: with tempfile.TemporaryDirectory() as directory: path = Path(directory) / "help-baseline.json" path.write_text( json.dumps( { "schema_version": 1, "maximum_missing_exact_help": 3, } ), encoding="utf-8", ) self.assertEqual( 3, inventory._load_high_risk_help_baseline(path)[ "maximum_missing_exact_help" ], ) path.write_text( json.dumps( { "schema_version": 1, "maximum_missing_exact_help": -1, } ), encoding="utf-8", ) with self.assertRaisesRegex(ValueError, "non-negative integer"): inventory._load_high_risk_help_baseline(path) def test_declaration_strict_mode_rejects_high_risk_help_regression( self, ) -> None: result = { "translation_health": {"missing_catalog_entries": []}, "api": { "unclassified_endpoints": [], "stale_endpoint_declarations": [], }, "declaration_health": {}, "help_health": { "invalid_risk_annotations": [], "unresolved_exact_high_risk_help": [], "high_risk_help_without_german": [], "missing_exact_high_risk_help": [{"id": "example.delete"}], "baseline_maximum_missing": 0, "baseline_regression": True, }, } self.assertEqual( [ "1 high-risk controls lack exact F1 help; baseline permits at most 0" ], inventory._strict_failures( result, check_translations=False, check_endpoints=False, check_declarations=True, ), ) def test_fastapi_route_scanner_includes_router_prefix(self) -> None: tree = ast.parse( """ from fastapi import APIRouter router = APIRouter(prefix="/api/v1/items") @router.get("/{item_id}") def read_item(item_id: str): return item_id """ ) prefixes = inventory._router_prefixes(tree) function = next( node for node in ast.walk(tree) if isinstance(node, ast.FunctionDef) ) route = inventory._endpoint_from_decorator( function.decorator_list[0], prefixes=prefixes, ) self.assertEqual( route, { "method": "GET", "path": "/api/v1/items/{item_id}", "router": "router", }, ) def test_source_declarations_normalize_stable_control_and_contribution_ids( self, ) -> None: webui = { "fields": [ { "repository": "govoplan-example", "file": "webui/src/Example.tsx", "line": 12, "column": 3, "id": "govoplan-example.field.example.name.abc123", "idSource": "source_anchor", "explicitId": None, "context": "Example", "helpId": "govoplan-example.field.example.name.abc123.help", "helpDynamic": False, } ], "actions": [], "contributions": [ { "repository": "govoplan-example", "file": "webui/src/module.ts", "line": 20, "column": 5, "kind": "frontend_route", "id": "/examples/:exampleId", "path": "/examples/:exampleId", } ], "translationCatalog": {"en": {}, "de": {}}, } manifests = [{"repository": "govoplan-example", "id": "examples"}] declarations = inventory._source_interface_declarations(webui, manifests) keys = {item["key"] for item in declarations} self.assertIn("field:examples.field.example.name.abc123", keys) self.assertIn( "help:examples.field.example.name.abc123.help", keys, ) self.assertIn( "frontend_route:examples.route.examples.exampleid", keys, ) def test_declaration_health_rejects_duplicate_and_undeclared_source_ids( self, ) -> None: declaration = { "key": "frontend_route:example.route.unlisted", "id": "example.route.unlisted", "module_id": "example", "kind": "frontend_route", "origin": "webui_contribution", } manifests = [ { "id": "example", "repository": "govoplan-example", "interface_catalog": {"declarations": []}, } ] health = inventory._declaration_health( [declaration, dict(declaration)], manifests, ) self.assertEqual(1, len(health["duplicate_ids"])) self.assertEqual(1, len(health["undeclared_source_surfaces"])) def test_runtime_snapshot_comparison_accepts_an_installed_subset(self) -> None: manifests = [ { "id": "one", "interface_catalog": { "contract_version": "1", "module_id": "one", "module_version": "1.0.0", "digest": "sha256:one", }, }, { "id": "two", "interface_catalog": { "contract_version": "1", "module_id": "two", "module_version": "1.0.0", "digest": "sha256:two", }, }, ] snapshot = { "contract_version": "1", "modules": [dict(manifests[1]["interface_catalog"])], } comparison = inventory._compare_runtime_snapshot(snapshot, manifests) self.assertEqual(["two"], comparison["matched_modules"]) self.assertEqual([], comparison["mismatches"]) snapshot["modules"][0]["digest"] = "sha256:changed" comparison = inventory._compare_runtime_snapshot(snapshot, manifests) self.assertEqual("digest_mismatch", comparison["mismatches"][0]["reason"]) if __name__ == "__main__": unittest.main()