import json import tempfile import unittest from pathlib import Path from unittest.mock import patch from app.core.config import settings from app.services.build_info_service import ( _expected_route_paths, get_runtime_build_info, remember_registered_route_paths, ) class BuildInfoServiceTests(unittest.TestCase): def tearDown(self) -> None: remember_registered_route_paths([]) def test_runtime_build_info_prefers_configured_manifest_and_reports_registered_surface(self) -> None: with tempfile.TemporaryDirectory() as temp_dir: manifest_path = Path(temp_dir) / "release_manifest.json" manifest_path.write_text( json.dumps( { "package_name": "domaincheck_release_demo", "generated_at": "2026-04-18T12:00:00", "commit_sha": "bd6bcb2", "commit_ref": "main", "sha256": "demo-sha256", }, ensure_ascii=False, ), encoding="utf-8", ) route_paths = list(_expected_route_paths().values()) remember_registered_route_paths(route_paths) with patch.multiple( settings, build_manifest_path=str(manifest_path), build_commit_sha="", build_commit_ref="", build_generated_at="", build_package_name="", build_checksum="", build_source_label="", ): payload = get_runtime_build_info() self.assertEqual("configured_manifest", payload["source"]) self.assertEqual("domaincheck_release_demo", payload["package_name"]) self.assertEqual("bd6bcb2", payload["commit_sha"]) self.assertEqual("main", payload["commit_ref"]) self.assertEqual("demo-sha256", payload["checksum"]) self.assertEqual(str(manifest_path), payload["manifest_path"]) self.assertTrue(payload["route_surface"]["surface_complete"]) self.assertEqual([], payload["route_surface"]["missing_keys"]) self.assertEqual("registered", payload["route_surface"]["mode"]) self.assertIn("repository_capabilities", payload) self.assertIn("supports_install_command_block", payload["repository_capabilities"]) self.assertIn("supports_multi_layout_bootstrap", payload["repository_capabilities"]) def test_runtime_build_info_env_override_wins_and_missing_routes_are_visible(self) -> None: with patch.multiple( settings, build_manifest_path="", build_commit_sha="246838ae4c07", build_commit_ref="main", build_generated_at="2026-04-18T12:10:00", build_package_name="domaincheck_release_env", build_checksum="env-sha256", build_source_label="env-override", ): payload = get_runtime_build_info(route_paths=[_expected_route_paths()["ops_contracts"]]) self.assertEqual("env-override", payload["source"]) self.assertEqual("domaincheck_release_env", payload["package_name"]) self.assertEqual("246838ae4c07", payload["commit_sha"]) self.assertEqual("main", payload["commit_ref"]) self.assertEqual("env-sha256", payload["checksum"]) self.assertFalse(payload["route_surface"]["surface_complete"]) self.assertIn("ops_stack_diagnosis", payload["route_surface"]["missing_keys"]) self.assertIn("ops_migration_source_profile", payload["route_surface"]["missing_keys"]) self.assertIn("ops_migration_preview", payload["route_surface"]["missing_keys"]) self.assertIn("ops_migration_execute", payload["route_surface"]["missing_keys"]) self.assertIn("ops_node_onboarding_bootstrap_preview", payload["route_surface"]["missing_keys"]) self.assertIn("ops_node_onboarding_bootstrap_execute", payload["route_surface"]["missing_keys"]) self.assertIn("ops_node_onboarding_acceptance_preview", payload["route_surface"]["missing_keys"]) self.assertIn("ops_node_onboarding_acceptance_execute", payload["route_surface"]["missing_keys"]) self.assertIn("ops_node_onboarding_recovery_preview", payload["route_surface"]["missing_keys"]) self.assertIn("ops_node_onboarding_recovery_execute", payload["route_surface"]["missing_keys"]) self.assertIn("ops_node_scene_log", payload["route_surface"]["missing_keys"]) self.assertIn("runtime_build_info", payload["route_surface"]["missing_keys"]) self.assertEqual("registered", payload["route_surface"]["mode"]) self.assertIn("repository_capabilities", payload) self.assertIn("supports_install_command_block", payload["repository_capabilities"]) if __name__ == "__main__": unittest.main()