from __future__ import annotations import importlib.util import json import sys import tempfile import unittest from pathlib import Path from unittest.mock import patch ROOT = Path(__file__).resolve().parents[1] SCRIPT = ROOT / "scripts" / "normalize_backend_result.py" SPEC = importlib.util.spec_from_file_location("normalize_backend_result", SCRIPT) assert SPEC is not None and SPEC.loader is not None MODULE = importlib.util.module_from_spec(SPEC) sys.modules[SPEC.name] = MODULE SPEC.loader.exec_module(MODULE) class NormalizeBackendResultTests(unittest.TestCase): def test_unsupported_surfaceir_snapshot_does_not_block_native_publish(self) -> None: with tempfile.TemporaryDirectory() as temporary: directory = Path(temporary) step_path = directory / "model.step" metadata_path = directory / "backend-metadata.json" output_path = directory / "model.designir.json" step_path.write_bytes(b"ISO-10303-21;\nEND-ISO-10303-21;\n") metadata_path.write_text( json.dumps( { "parameters": [ { "name": "module", "value": 2.5, "unit": "mm", "editable": True, "binding_kind": "native_python", "parameter_path": "PARAMETERS.module", "regenerate_adapter": "simplecadapi", } ] } ), encoding="utf-8", ) with patch.object( MODULE.surfaceir_pipeline, "extract_surfaceir", side_effect=ValueError("Unsupported surface type: 8"), ): result = MODULE.normalize_backend_result( request="standard spur gear", backend="simplecadapi", source_of_truth="model_graph", step_path=step_path, output_path=output_path, model_id="spur_gear", family="simplecadapi_native_model", native_source_path="model.simplecadapi.py", backend_graph_path="model.simplecad.model.json", metadata_path=metadata_path, validation_paths=["backend-validation.json"], ) payload = json.loads(output_path.read_text(encoding="utf-8")) self.assertTrue(result["valid"]) self.assertEqual("fully_semantic_parametric", result["reconstruction_mode"]) self.assertEqual("unavailable", result["surface_snapshot"]["status"]) self.assertNotIn("surface_layer", payload) self.assertEqual("partial", payload["semantic_layer"]["reconstruction_status"]) snapshot_stage = payload["semantic_layer"]["construction_stages"][1] self.assertEqual("unavailable", snapshot_stage["status"]) self.assertEqual("Unsupported surface type: 8", snapshot_stage["error"])