Files
isphere-ai-bridge/tests/test_real_lab.py
2026-07-05 14:52:23 +08:00

93 lines
3.7 KiB
Python

from __future__ import annotations
import asyncio
import unittest
from isphere_ai_bridge import real_lab
class RealLoggedInLabTests(unittest.TestCase):
def test_plan_tree_reports_ready_and_blocked_phases(self) -> None:
tree = real_lab.plan_tree()
self.assertEqual("real-loggedin-planning", tree["mode"])
self.assertEqual("A", tree["phases"][0]["id"])
self.assertEqual("ready-now", tree["phases"][0]["status"])
self.assertTrue(
any(phase["status"] == "blocked-waiting-real-data" for phase in tree["phases"])
)
def test_required_files_checklist_has_expected_sections(self) -> None:
checklist = real_lab.required_files_checklist()
section_ids = {section["id"] for section in checklist["sections"]}
self.assertTrue({"install_dir", "user_data", "logged_in_window"}.issubset(section_ids))
self.assertEqual("copy-later", checklist["recommended_timing"])
def test_action_contract_requires_approval_for_send_and_file_upload(self) -> None:
contract = real_lab.action_contract()
actions = {action["name"]: action for action in contract["actions"]}
self.assertFalse(actions["real_lab_search_contacts"]["requires_approval"])
self.assertTrue(actions["real_lab_send_after_approval"]["requires_approval"])
self.assertTrue(actions["real_lab_send_file_after_approval"]["requires_approval"])
self.assertEqual("no-login-automation", contract["hard_limits"][0])
def test_status_and_scan_windows_are_structured_without_real_client(self) -> None:
status = real_lab.status()
scan = real_lab.scan_windows()
self.assertIn("ready", status)
self.assertIn("process_candidates", status)
self.assertIn("next_step", status)
self.assertIn("windows", scan)
self.assertIn("next_step", scan)
def test_win_helper_version_and_self_check_are_structured(self) -> None:
built = real_lab.build_win_helper()
self.assertTrue(built["ok"], built)
version = real_lab.win_helper_version()
self.assertTrue(version["ok"], version)
self.assertEqual("version", version["op"])
self.assertEqual("ISphereWinHelper", version["data"]["helper_name"])
self_check = real_lab.win_helper_self_check()
self.assertTrue(self_check["ok"], self_check)
self.assertEqual("self_check", self_check["op"])
self.assertIn("uia_available", self_check["data"])
def test_win_helper_scan_and_missing_uia_dump_are_structured(self) -> None:
built = real_lab.build_win_helper()
self.assertTrue(built["ok"], built)
scan = real_lab.win_helper_scan_windows(include_all_visible=True)
self.assertTrue(scan["ok"], scan)
self.assertEqual("scan_windows", scan["op"])
self.assertIsInstance(scan["data"]["windows"], list)
dump = real_lab.win_helper_dump_uia("0x0")
self.assertFalse(dump["ok"], dump)
self.assertIn(dump["error"]["code"], {"WINDOW_NOT_FOUND", "UIA_DUMP_FAILED"})
def test_real_lab_tools_are_registered(self) -> None:
from isphere_ai_bridge.server import mcp
names = [tool.name for tool in asyncio.run(mcp.list_tools())]
required = {
"real_lab_plan_tree",
"real_lab_required_files",
"real_lab_action_contract",
"real_lab_status",
"real_lab_scan_windows",
"real_lab_win_helper_version",
"real_lab_win_helper_self_check",
"real_lab_win_helper_scan_windows",
"real_lab_win_helper_dump_uia",
}
self.assertTrue(required.issubset(set(names)))
if __name__ == "__main__":
unittest.main()