AutoRpa/state_center/tests/test_yisaiqi_contract_creat...

113 lines
3.9 KiB
Python

import json
from rpa_yisaiqi.callback_client import StateCenterClient
from rpa_yisaiqi.contract_create_node import (
ContractCreateInput,
LoginFailed,
execute_contract_create,
)
class FakeHttp:
def __init__(self, responses=None):
self.requests = []
self.responses = list(responses or [{"ok": True}, {"ok": True, "next_node": "CONTRACT_APPROVE_WAIT"}])
def __call__(self, request, timeout):
body = json.loads(request.data.decode("utf-8")) if request.data else None
self.requests.append(
{
"url": request.full_url,
"headers": dict(request.header_items()),
"body": body,
"timeout": timeout,
}
)
return FakeResponse(self.responses.pop(0))
class FakeResponse:
def __init__(self, payload):
self.payload = payload
def __enter__(self):
return self
def __exit__(self, exc_type, exc, tb):
return False
def read(self):
return json.dumps(self.payload).encode("utf-8")
def test_state_center_client_sends_agent_token_and_json_body():
http = FakeHttp([{"ok": True}])
client = StateCenterClient("http://state-center:8000/", "dev-agent-token", opener=http)
result = client.start_node("JOB-1", "CONTRACT_CREATE", attempt_no=2, operator="agent")
assert result == {"ok": True}
assert http.requests[0]["url"] == "http://state-center:8000/api/jobs/JOB-1/nodes/CONTRACT_CREATE/start"
assert http.requests[0]["headers"]["X-agent-token"] == "dev-agent-token"
assert http.requests[0]["body"] == {
"attemptNo": 2,
"executorPlatform": "iS-RPA",
"operator": "agent",
}
def test_state_center_client_escapes_non_ascii_path_parts():
http = FakeHttp([{"ok": True}])
client = StateCenterClient("http://state-center:8000", "dev-agent-token", opener=http)
client.start_node("YYC-合同节点联调-001", "CONTRACT_CREATE")
assert http.requests[0]["url"] == (
"http://state-center:8000/api/jobs/"
"YYC-%E5%90%88%E5%90%8C%E8%8A%82%E7%82%B9%E8%81%94%E8%B0%83-001"
"/nodes/CONTRACT_CREATE/start"
)
def test_contract_create_calls_start_then_complete_with_contract_number():
http = FakeHttp()
client = StateCenterClient("http://state-center:8000", "dev-agent-token", opener=http)
spec = ContractCreateInput(
job_id="JOB-1",
supplier_name="重庆亿昊药业",
order_date="2026-08-11",
source_type="YYC",
contract_system_no="HT-20260811-001",
)
result = execute_contract_create(spec, client)
assert result["next_node"] == "CONTRACT_APPROVE_WAIT"
assert [request["url"].split("/")[-1] for request in http.requests] == ["start", "complete"]
assert http.requests[1]["body"]["businessRefs"] == {"contractSystemNo": "HT-20260811-001"}
assert http.requests[1]["body"]["summary"]["supplierName"] == "重庆亿昊药业"
assert http.requests[1]["body"]["summary"]["contractDate"] == "2026-08-11"
def test_contract_create_reports_login_failure_to_state_center():
http = FakeHttp([{"ok": True}, {"ok": True, "job_status": "FAILED_RETRYABLE"}])
client = StateCenterClient("http://state-center:8000", "dev-agent-token", opener=http)
spec = ContractCreateInput(
job_id="JOB-1",
supplier_name="重庆亿昊药业",
order_date="2026-08-11",
source_type="YYC",
contract_system_no="HT-20260811-001",
)
def failing_runner(_spec):
raise LoginFailed("合同系统登录失败")
result = execute_contract_create(spec, client, contract_runner=failing_runner)
assert result["job_status"] == "FAILED_RETRYABLE"
assert http.requests[1]["url"].endswith("/api/jobs/JOB-1/nodes/CONTRACT_CREATE/fail")
assert http.requests[1]["body"]["errorCode"] == "SYS_LOGIN_FAIL"
assert http.requests[1]["body"]["retryable"] is True
assert http.requests[1]["body"]["routeRole"] == "OPS"