93 lines
3.7 KiB
Python
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()
|