import importlib import json import sys import tempfile import types import unittest from pathlib import Path REPO_ROOT = Path(__file__).resolve().parents[2] MODULE_DIR = REPO_ROOT / "src" / "Mod" / "FreeCADExchange" if str(MODULE_DIR) not in sys.path: sys.path.insert(0, str(MODULE_DIR)) def _install_fake_modules(): fake_freecad = types.ModuleType("FreeCAD") fake_freecad.ActiveDocument = object() fake_freecad.Console = types.SimpleNamespace( PrintMessage=lambda *args, **kwargs: None, PrintWarning=lambda *args, **kwargs: None, PrintError=lambda *args, **kwargs: None, PrintLog=lambda *args, **kwargs: None, ) sys.modules["FreeCAD"] = fake_freecad fake_gui = types.ModuleType("FreeCADGui") fake_gui.getMainWindow = lambda: None sys.modules["FreeCADGui"] = fake_gui fake_device_import = types.ModuleType("DeviceImport") fake_device_import.DeviceImportError = RuntimeError fake_device_import.import_devices_from_payload = lambda *args, **kwargs: {} sys.modules["DeviceImport"] = fake_device_import fake_device_preview = types.ModuleType("DevicePreview") fake_device_preview.find_parent_qet_device_object = lambda obj: None fake_device_preview.is_preview_document_name = lambda name: False fake_device_preview.open_preview_for_device_object = lambda obj: None sys.modules["DevicePreview"] = fake_device_preview fake_terminal_import = types.ModuleType("TerminalImport") fake_terminal_import.TerminalImportError = RuntimeError sys.modules["TerminalImport"] = fake_terminal_import calls = [] fake_wiring = types.ModuleType("WiringObjects") fake_wiring.initialize_wiring_scene = lambda doc, project_uuid="": calls.append((doc, project_uuid)) or "root" sys.modules["WiringObjects"] = fake_wiring wire_calls = [] fake_wiring_import = types.ModuleType("WiringImport") fake_wiring_import.WiringImportError = RuntimeError fake_wiring_import.import_wire_tasks_from_payload = ( lambda payload, doc=None: wire_calls.append((payload, doc)) or {"imported_tasks": 1, "updated_tasks": 0, "warnings": []} ) sys.modules["WiringImport"] = fake_wiring_import class _QObject: def __init__(self, *args, **kwargs): pass fake_qt_core = types.SimpleNamespace( QObject=_QObject, QEvent=types.SimpleNamespace(MouseButtonDblClick=1), QTimer=types.SimpleNamespace(singleShot=lambda *args, **kwargs: None), ) fake_qt_widgets = types.SimpleNamespace( QWidget=object, QMessageBox=types.SimpleNamespace( information=lambda *args, **kwargs: None, critical=lambda *args, **kwargs: None, ), ) fake_pyside = types.ModuleType("PySide6") fake_pyside.QtCore = fake_qt_core fake_pyside.QtWidgets = fake_qt_widgets sys.modules["PySide6"] = fake_pyside return fake_freecad, calls, wire_calls class ExchangeBootstrapWiringTest(unittest.TestCase): def test_initialize_wiring_scene_uses_active_document_and_project_uuid(self): app, calls, _wire_calls = _install_fake_modules() sys.modules.pop("ExchangeBootstrap", None) bootstrap = importlib.import_module("ExchangeBootstrap") result = bootstrap._initialize_wiring_scene({"project_uuid": "project-1"}) self.assertEqual("root", result) self.assertEqual([(app.ActiveDocument, "project-1")], calls) def test_import_wiring_tasks_uses_active_document_and_payload(self): app, _calls, wire_calls = _install_fake_modules() sys.modules.pop("ExchangeBootstrap", None) bootstrap = importlib.import_module("ExchangeBootstrap") payload = {"project_uuid": "project-1", "wires": [{"wire_id": "wire-1"}]} result = bootstrap._import_wiring_tasks(payload) self.assertEqual({"imported_tasks": 1, "updated_tasks": 0, "warnings": []}, result) self.assertEqual([(payload, app.ActiveDocument)], wire_calls) def test_load_exchange_payload_keeps_wire_entries(self): _install_fake_modules() sys.modules.pop("ExchangeBootstrap", None) bootstrap = importlib.import_module("ExchangeBootstrap") payload = { "schema_version": "1.2", "project_uuid": "project-1", "devices": [], "terminals": [], "device_models": [], "wires": [ { "wire_id": "wire-1", "wire_mark": "W001", "start_terminal_uuid": "terminal-a", "end_terminal_uuid": "terminal-b", } ], } with tempfile.TemporaryDirectory() as temp_dir: path = Path(temp_dir) / "2d_to_3d.json" path.write_text(json.dumps(payload), encoding="utf-8") normalized = bootstrap.load_exchange_payload(str(path)) self.assertEqual(1, len(normalized["wires"])) self.assertEqual("wire-1", normalized["wires"][0]["wire_id"]) self.assertEqual("W001", normalized["wires"][0]["wire_mark"]) if __name__ == "__main__": unittest.main()