Files
aiagent/backend/tests/test_nodes_phase4.py
2026-01-22 09:59:02 +08:00

137 lines
4.1 KiB
Python
Raw Permalink 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.
import pytest
from app.services.workflow_engine import WorkflowEngine
def _make_engine_with_node(node):
"""构造仅含单节点的工作流引擎"""
wf_data = {"nodes": [node], "edges": []}
return WorkflowEngine(workflow_id="wf_test", workflow_data=wf_data)
@pytest.mark.asyncio
async def test_subworkflow_mapping():
node = {
"id": "sub-1",
"type": "subworkflow",
"data": {
"workflow_id": "child_wf",
"input_mapping": {"mapped": "source"},
},
}
engine = _make_engine_with_node(node)
result = await engine.execute_node(node, {"source": 123, "other": 1})
assert result["status"] == "success"
assert result["output"]["workflow_id"] == "child_wf"
assert result["output"]["input"]["mapped"] == 123
@pytest.mark.asyncio
async def test_code_python_success():
node = {
"id": "code-1",
"type": "code",
"data": {
"language": "python",
"code": "result = input_data['x'] * 2",
},
}
engine = _make_engine_with_node(node)
result = await engine.execute_node(node, {"x": 3})
assert result["status"] == "success"
assert result["output"] == 6
@pytest.mark.asyncio
async def test_code_unsupported_language():
node = {
"id": "code-2",
"type": "code",
"data": {"language": "go", "code": "result = 1"},
}
engine = _make_engine_with_node(node)
result = await engine.execute_node(node, {})
assert result["status"] == "success"
assert "不支持的语言" in result["output"]["error"]
@pytest.mark.asyncio
async def test_oauth_mock_token():
node = {
"id": "oauth-1",
"type": "oauth",
"data": {"provider": "google", "client_id": "id", "client_secret": "sec"},
}
engine = _make_engine_with_node(node)
result = await engine.execute_node(node, {})
assert result["status"] == "success"
token = result["output"]
assert token["access_token"].startswith("mock_access_token_google")
assert token["token_type"] == "Bearer"
@pytest.mark.asyncio
async def test_validator_reject_and_continue():
# reject 分支 -> failed
node_reject = {
"id": "val-1",
"type": "validator",
"data": {"schema": {"type": "object"}, "on_error": "reject"},
}
engine = _make_engine_with_node(node_reject)
res_reject = await engine.execute_node(node_reject, "bad_type")
assert res_reject["status"] == "failed"
# continue 分支 -> success 且 warning
node_continue = {
"id": "val-2",
"type": "validator",
"data": {"schema": {"type": "object"}, "on_error": "continue"},
}
engine = _make_engine_with_node(node_continue)
res_continue = await engine.execute_node(node_continue, "bad_type")
assert res_continue["status"] == "success"
assert "warning" in res_continue
@pytest.mark.asyncio
async def test_batch_split_group_aggregate():
data = list(range(5))
# split
node_split = {
"id": "batch-1",
"type": "batch",
"data": {"batch_size": 2, "mode": "split"},
}
engine = _make_engine_with_node(node_split)
res_split = await engine.execute_node(node_split, data)
assert res_split["status"] == "success"
assert res_split["output"][0] == [0, 1]
assert res_split["output"][1] == [2, 3]
assert res_split["output"][2] == [4]
# group同 split 逻辑)
node_group = {
"id": "batch-2",
"type": "batch",
"data": {"batch_size": 3, "mode": "group"},
}
engine = _make_engine_with_node(node_group)
res_group = await engine.execute_node(node_group, data)
assert res_group["status"] == "success"
assert res_group["output"][0] == [0, 1, 2]
assert res_group["output"][1] == [3, 4]
# aggregate
node_agg = {
"id": "batch-3",
"type": "batch",
"data": {"mode": "aggregate"},
}
engine = _make_engine_with_node(node_agg)
res_agg = await engine.execute_node(node_agg, data)
assert res_agg["status"] == "success"
assert res_agg["output"]["count"] == 5
assert res_agg["output"]["samples"][:2] == [0, 1]