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

168 lines
5.0 KiB
Python

from __future__ import annotations
import asyncio
import json
import sys
from pathlib import Path
import pytest
APP = Path(__file__).resolve().parents[1] / "app"
if str(APP) not in sys.path:
sys.path.insert(0, str(APP))
from routers import fleet, unified
def _devices(*ids: str):
return [
{"device_id": device_id, "project_id": "2130", "capabilities": ["hook"]}
for device_id in ids
]
def test_fleet_write_requires_confirm_even_for_one_device(monkeypatch):
async def fake_select(**kwargs):
return _devices("device-1")
monkeypatch.setattr(fleet, "_select_devices", fake_select)
response = asyncio.run(
fleet.fleet_execute(
fleet.FleetExecuteRequest(
device_ids=["device-1"],
platform="wechat",
action="send_message",
params={"to_id": "filehelper", "content": "contract"},
)
)
)
assert response["code"] == 200
assert response["success"] is False
assert response["trace_id"]
assert response["raw_rpc_receipt"]["confirm_required"] is True
assert response["data"]["success"] is False
assert response["data"]["confirm_required"] is True
def test_fleet_dry_run_does_not_execute(monkeypatch):
async def fake_select(**kwargs):
return _devices("device-1")
monkeypatch.setattr(fleet, "_select_devices", fake_select)
async def should_not_execute(*args, **kwargs):
pytest.fail("dry_run 不应下发设备命令")
monkeypatch.setattr(unified, "_execute_skill", should_not_execute)
response = asyncio.run(
fleet.fleet_execute(
fleet.FleetExecuteRequest(
device_ids=["device-1"],
platform="wechat",
action="send_message",
dry_run=True,
)
)
)
assert response["code"] == 200
assert response["channel_used"] == "fleet/dry_run"
assert response["raw_rpc_receipt"]["executed"] is False
assert response["readback"] is None
assert response["data"]["dry_run"] is True
assert response["data"]["success"] is True
def test_fleet_uses_explicit_business_success_not_code(monkeypatch):
async def fake_select(**kwargs):
return _devices("device-1")
monkeypatch.setattr(fleet, "_select_devices", fake_select)
async def fake_execute(*args, **kwargs):
return {
"code": 200,
"success": False,
"error_code": "no_receiver_registered",
"error_message": "设备端没有接收器",
"channel_used": "server/frida",
}
monkeypatch.setattr(unified, "_execute_skill", fake_execute)
response = asyncio.run(
fleet.fleet_execute(
fleet.FleetExecuteRequest(
device_ids=["device-1"],
platform="wechat",
action="get_hook_status",
confirm=True,
)
)
)
item = response["data"]["results"][0]
assert response["data"]["success"] is False
assert response["data"]["success_count"] == 0
assert item["success"] is False
assert item["result"]["error_code"] == "no_receiver_registered"
assert response["trace_id"]
assert response["raw_rpc_receipt"]["operation"] == "fleet_execute"
def test_fleet_timeout_returns_retryable_structured_error(monkeypatch):
async def fake_select(**kwargs):
return _devices("device-1")
monkeypatch.setattr(fleet, "_select_devices", fake_select)
async def fake_execute(*args, **kwargs):
raise asyncio.TimeoutError
monkeypatch.setattr(unified, "_execute_skill", fake_execute)
response = asyncio.run(
fleet.fleet_execute(
fleet.FleetExecuteRequest(
device_ids=["device-1"],
platform="wechat",
action="get_hook_status",
confirm=True,
)
)
)
assert response.status_code == 503
body = json.loads(response.body)
result = body["data"]["results"][0]["result"]
assert body["data"]["success"] is False
assert result["code"] == 504
assert result["error_code"] == "timeout"
assert result["retryable"] is True
assert result["trace_id"]
assert result["raw_rpc_receipt"]["channel"] == "websocket/timeout"
def test_fleet_wechat_forces_hook_only(monkeypatch):
async def fake_select(**kwargs):
return _devices("device-1")
monkeypatch.setattr(fleet, "_select_devices", fake_select)
received = {}
async def fake_execute(*args, **kwargs):
received.update(kwargs)
return {"code": 200, "data": {"success": True}, "trace_id": "rpc-trace"}
monkeypatch.setattr(unified, "_execute_skill", fake_execute)
response = asyncio.run(
fleet.fleet_execute(
fleet.FleetExecuteRequest(
device_ids=["device-1"], platform="wechat", action="get_hook_status", confirm=True
)
)
)
assert received["hook_only"] is True
assert response["channel_used"] == "frida_rpc"
assert response["data"]["results"][0]["trace_id"] == "rpc-trace"