Files
workphone-sdk/sdk/tests/test_hook_executor.py

129 lines
5.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
HookExecutor 单元测试 (H31)
测试 HookExecutor 在 Frida 未连接/已连接 两种状态下的行为。
使用 Mock 模拟 FridaManager不需要真机。
"""
import sys
import os
import unittest
from unittest.mock import MagicMock, patch
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "agent"))
from hook.hook_executor import HookExecutor, ACTION_TO_RPC
from hook.frida_manager import FridaManager
class TestHookExecutorOffline(unittest.TestCase):
"""FridaManager 未连接时 HookExecutor 应安全返回错误"""
def setUp(self):
self.mgr = MagicMock(spec=FridaManager)
self.mgr.connected = False
self.executor = HookExecutor(self.mgr)
def test_available_false_when_disconnected(self):
self.assertFalse(self.executor.available)
def test_execute_returns_error_when_disconnected(self):
result = self.executor.execute("send_message", {"to_id": "test", "content": "hello"})
self.assertFalse(result["success"])
self.assertIn("不可用", result["error"])
self.assertEqual(result["channel"], "hook")
def test_supports_known_actions(self):
for action in ACTION_TO_RPC:
self.assertTrue(self.executor.supports(action), f"{action} should be supported")
def test_supports_returns_false_for_unknown(self):
self.assertFalse(self.executor.supports("fly_to_moon"))
def test_get_status(self):
self.mgr.get_status.return_value = {"connected": False, "device": None}
status = self.executor.get_status()
self.assertFalse(status["available"])
self.assertIsInstance(status["supported_actions"], list)
self.assertGreater(len(status["supported_actions"]), 10)
class TestHookExecutorOnline(unittest.TestCase):
"""FridaManager 已连接时 HookExecutor 应正确路由 RPC 调用"""
def setUp(self):
self.mgr = MagicMock(spec=FridaManager)
self.mgr.connected = True
self.mgr.call_rpc.return_value = {"success": True, "message_id": "msg_123"}
self.executor = HookExecutor(self.mgr)
def test_available_true_when_connected(self):
self.assertTrue(self.executor.available)
def test_send_message_routes_to_rpc(self):
params = {"to_id": "wxid_abc", "content": "hello"}
result = self.executor.execute("send_message", params)
self.mgr.call_rpc.assert_called_once_with("sendMessage", params)
self.assertTrue(result["success"])
self.assertEqual(result["channel"], "hook")
def test_get_contacts_routes_to_rpc(self):
self.mgr.call_rpc.return_value = {"success": True, "contacts": [], "count": 0}
result = self.executor.execute("get_contacts", {"limit": 100})
self.mgr.call_rpc.assert_called_once_with("getContacts", {"limit": 100})
self.assertTrue(result["success"])
def test_unknown_action_returns_error(self):
result = self.executor.execute("nonexistent_action", {})
self.assertFalse(result["success"])
self.assertIn("不支持", result["error"])
def test_all_actions_map_to_rpc(self):
for action, rpc_method in ACTION_TO_RPC.items():
self.mgr.call_rpc.reset_mock()
self.mgr.call_rpc.return_value = {"success": True}
self.executor.execute(action, {"test": True})
self.mgr.call_rpc.assert_called_once_with(rpc_method, {"test": True})
def test_rpc_failure_propagates(self):
self.mgr.call_rpc.return_value = {"success": False, "error": "微信未运行"}
result = self.executor.execute("send_message", {"to_id": "x", "content": "y"})
self.assertFalse(result["success"])
self.assertEqual(result["error"], "微信未运行")
# H19 好友管理动作
def test_add_friend(self):
self.mgr.call_rpc.return_value = {"success": True, "user_id": "test_user"}
result = self.executor.execute("add_friend", {"user_id": "test_user", "message": "hi"})
self.mgr.call_rpc.assert_called_once_with("addFriend", {"user_id": "test_user", "message": "hi"})
def test_accept_friend(self):
self.mgr.call_rpc.return_value = {"success": True}
result = self.executor.execute("accept_friend", {"encrypt_username": "v3_xxx", "ticket": "t_xxx"})
self.assertTrue(result["success"])
# H22 群管理动作
def test_create_group(self):
self.mgr.call_rpc.return_value = {"success": True}
result = self.executor.execute("create_group", {"member_ids": ["a", "b"], "topic": "测试群"})
self.mgr.call_rpc.assert_called_once()
def test_invite_to_group(self):
self.mgr.call_rpc.return_value = {"success": True}
result = self.executor.execute("invite_to_group", {"group_id": "xxx@chatroom", "member_ids": ["a"]})
self.assertTrue(result["success"])
# H20/H21 朋友圈动作
def test_post_moments(self):
self.mgr.call_rpc.return_value = {"success": True, "sns_id": "sns_123"}
result = self.executor.execute("post_moments", {"content": "今天天气真好"})
self.assertTrue(result["success"])
def test_like_moments(self):
self.mgr.call_rpc.return_value = {"success": True}
result = self.executor.execute("like_moments", {"sns_id": "12345"})
self.assertTrue(result["success"])
if __name__ == "__main__":
unittest.main()