from __future__ import annotations import os import tempfile import unittest from pathlib import Path from isphere_ai_bridge import native_helper def _has_framework_csc() -> bool: windir = Path(os.environ.get("WINDIR", r"C:\Windows")) return ( windir / "Microsoft.NET" / "Framework64" / "v4.0.30319" / "csc.exe" ).exists() or ( windir / "Microsoft.NET" / "Framework" / "v4.0.30319" / "csc.exe" ).exists() class NativeHelperTests(unittest.TestCase): def test_helper_paths_are_actionable(self) -> None: paths = native_helper.helper_paths() self.assertIn("build_command", paths) self.assertTrue(paths["build_script_exists"]) self.assertTrue(paths["default_client_dir_exists"]) @unittest.skipUnless(_has_framework_csc(), ".NET Framework csc.exe is required") def test_native_helper_build_inspect_and_offline_protocol(self) -> None: build = native_helper.build_native_helper() self.assertTrue(build["ok"], build) self.assertEqual(0, build["returncode"]) self.assertTrue(Path(build["output"]).exists()) self.assertTrue(Path(build["resource_stub"]).exists()) self.assertEqual("x86", build["platform"]) inspect = native_helper.native_lab_inspect() self.assertTrue(inspect["ok"], inspect) self.assertTrue(inspect["required_ready"]) type_names = {item["name"] for item in inspect["types"]} self.assertIn("IMPP.Client.frmMain", type_names) self.assertIn("IMPP.Client.Business.ChatManager.SingleChat.frmP2PChat", type_names) bootstrap = native_helper.native_lab_probe_main_window() self.assertTrue(bootstrap["ok"], bootstrap) bootstrap_steps = {item["name"]: item["ok"] for item in bootstrap["steps"]} self.assertTrue(bootstrap_steps["imppmanager_update_user"]) self.assertFalse(bootstrap["main_window_constructed"]) constructed = native_helper.native_lab_probe_main_window( construct=True, probe_chat=True, probe_actions=True, probe_files=True, user_jid="mock-bob@offline.lab", text="native helper direct test", file_name="incoming-probe-native.txt", file_size=321, timeout_ms=15000, ) self.assertTrue(constructed["ok"], constructed) self.assertTrue(constructed["main_window_constructed"]) self.assertTrue(constructed["chat_model_constructed"]) self.assertTrue(constructed["chat_window_constructed"]) self.assertTrue(constructed["send_text_invoked"]) self.assertTrue(constructed["receive_text_invoked"]) self.assertTrue(constructed["file_send_control_constructed"]) self.assertTrue(constructed["file_receive_control_constructed"]) construct_steps = {item["name"]: item["ok"] for item in constructed["steps"]} self.assertTrue(construct_steps["patch_problematic_ui_methods"]) self.assertTrue(construct_steps["instantiate_frmMain"]) self.assertTrue(construct_steps["instantiate_frmP2PChat"]) self.assertTrue(construct_steps["invoke_frmP2PChat_SaveAndShowMessage"]) self.assertTrue(construct_steps["invoke_frmP2PChat_ProccessRecvMessage"]) self.assertTrue(construct_steps["instantiate_UC_FileSend"]) self.assertTrue(construct_steps["instantiate_UC_FileReceive"]) direct_open = native_helper.native_lab_direct_open_main_window(timeout_ms=15000) self.assertTrue(direct_open["ok"], direct_open) self.assertTrue(direct_open["main_window_constructed"]) direct_send = native_helper.native_lab_direct_send_message( "mock-bob@offline.lab", "direct wrapper send", timeout_ms=15000, ) self.assertTrue(direct_send["ok"], direct_send) self.assertTrue(direct_send["send_text_invoked"]) self.assertFalse(direct_send["receive_text_invoked"]) direct_receive = native_helper.native_lab_direct_receive_message( "mock-bob@offline.lab", "direct wrapper receive", timeout_ms=15000, ) self.assertTrue(direct_receive["ok"], direct_receive) self.assertFalse(direct_receive["send_text_invoked"]) self.assertTrue(direct_receive["receive_text_invoked"]) direct_send_file = native_helper.native_lab_direct_send_file( "mock-bob@offline.lab", timeout_ms=15000, ) self.assertTrue(direct_send_file["ok"], direct_send_file) self.assertTrue(direct_send_file["file_send_control_constructed"]) self.assertFalse(direct_send_file["file_receive_control_constructed"]) direct_receive_file = native_helper.native_lab_direct_receive_file( "mock-bob@offline.lab", "direct-wrapper-incoming.txt", size=222, timeout_ms=15000, ) self.assertTrue(direct_receive_file["ok"], direct_receive_file) self.assertFalse(direct_receive_file["file_send_control_constructed"]) self.assertTrue(direct_receive_file["file_receive_control_constructed"]) with tempfile.TemporaryDirectory() as tmp: workspace = str(Path(tmp) / "native-lab") start = native_helper.native_lab_start(workspace=workspace, reset=True) self.assertTrue(start["started"]) self.assertEqual("offline-lab-native-helper", start["mode"]) self.assertEqual("inspected", start["native_bridge"]["status"]) users = native_helper.native_lab_search_users("文件", workspace=workspace) self.assertEqual(1, users["count"]) user_jid = users["users"][0]["jid"] opened = native_helper.native_lab_open_chat(user_jid, workspace=workspace) self.assertTrue(opened["opened"]) self.assertEqual("p2p-chat", opened["main_window"]["active_panel"]) sent = native_helper.native_lab_send_message( user_jid, "native helper test send", workspace=workspace, ) self.assertTrue(sent["sent"]) self.assertEqual("frmP2PChat.SaveAndShowMessage", sent["message"]["ui_hook"]) received_file = native_helper.native_lab_receive_file( user_jid, "incoming-native.txt", size=789, workspace=workspace, ) self.assertTrue(received_file["received"]) self.assertEqual( "frmP2PChat.ProccessRecvMessage -> UC_FileReceive", received_file["file_event"]["ui_hook"], ) conversation = native_helper.native_lab_read_conversation(user_jid, workspace=workspace) self.assertEqual(2, conversation["conversation"]["message_count"]) if __name__ == "__main__": unittest.main()