602 lines
23 KiB
Python
602 lines
23 KiB
Python
import os
|
|
|
|
from fastapi.testclient import TestClient
|
|
|
|
os.environ["DATABASE_URL"] = "sqlite:///:memory:"
|
|
|
|
from app.main import app
|
|
|
|
|
|
def test_task_create_confirm_get() -> None:
|
|
with TestClient(app) as client:
|
|
create_response = client.post(
|
|
"/api/agent/tasks",
|
|
headers={"X-Request-Id": "req-test-create-001"},
|
|
json={
|
|
"input_text": "deploy order-service 1.2.3 to test",
|
|
"channel": "WEB",
|
|
"session_id": "sess-001",
|
|
"tenant_id": "tenant-demo",
|
|
"context": {"preferred_env": "test"},
|
|
},
|
|
)
|
|
assert create_response.status_code == 200
|
|
task_id = create_response.json()["data"]["task_id"]
|
|
|
|
confirm_response = client.post(
|
|
f"/api/agent/tasks/{task_id}/confirm",
|
|
headers={"X-Request-Id": "req-test-confirm-001"},
|
|
json={"confirmed": True, "comment": "确认执行"},
|
|
)
|
|
assert confirm_response.status_code == 200
|
|
assert confirm_response.json()["data"]["software_a_task_id"] is not None
|
|
assert confirm_response.json()["data"]["software_a_task_status"] == "RUNNING"
|
|
|
|
get_response = client.get(f"/api/agent/tasks/{task_id}")
|
|
assert get_response.status_code == 200
|
|
assert get_response.json()["data"]["task_id"] == task_id
|
|
assert get_response.json()["data"]["software_a_task_id"] is not None
|
|
assert get_response.json()["data"]["software_a_task_status"] == "SUCCEEDED"
|
|
assert get_response.json()["data"]["tool_calls"][0]["tool_name"] == "software_a_deploy"
|
|
|
|
|
|
def test_high_risk_task_creates_approval_and_can_be_approved() -> None:
|
|
with TestClient(app) as client:
|
|
create_response = client.post(
|
|
"/api/agent/tasks",
|
|
json={
|
|
"input_text": "deploy order-service 1.2.3 to prod",
|
|
"channel": "WEB",
|
|
"session_id": "sess-002",
|
|
"tenant_id": "tenant-demo",
|
|
"context": {},
|
|
},
|
|
)
|
|
assert create_response.status_code == 200
|
|
task_id = create_response.json()["data"]["task_id"]
|
|
|
|
confirm_response = client.post(
|
|
f"/api/agent/tasks/{task_id}/confirm",
|
|
json={"confirmed": True, "comment": "need approval"},
|
|
)
|
|
assert confirm_response.status_code == 200
|
|
approval_id = confirm_response.json()["data"]["approval_id"]
|
|
assert approval_id is not None
|
|
assert confirm_response.json()["data"]["task_status"] == "PENDING_APPROVAL"
|
|
|
|
approval_response = client.get(f"/api/demo/approval/requests/{approval_id}")
|
|
assert approval_response.status_code == 200
|
|
assert approval_response.json()["data"]["approval_status"] == "PENDING"
|
|
|
|
decision_response = client.post(
|
|
f"/api/demo/approval/requests/{approval_id}/decision",
|
|
json={
|
|
"decision": "APPROVED",
|
|
"comment": "approved",
|
|
"operator": {"user_id": "u2001", "user_name": "bob"},
|
|
},
|
|
)
|
|
assert decision_response.status_code == 200
|
|
assert decision_response.json()["data"]["approval_status"] == "APPROVED"
|
|
|
|
get_task_response = client.get(f"/api/agent/tasks/{task_id}")
|
|
assert get_task_response.status_code == 200
|
|
assert get_task_response.json()["data"]["task_status"] == "RUNNING"
|
|
assert get_task_response.json()["data"]["approval_status"] == "APPROVED"
|
|
assert get_task_response.json()["data"]["software_a_task_id"] is not None
|
|
assert get_task_response.json()["data"]["software_a_task_status"] == "SUCCEEDED"
|
|
|
|
|
|
def test_demo_identity_and_software_a_endpoints() -> None:
|
|
with TestClient(app) as client:
|
|
login_response = client.post(
|
|
"/api/demo/identity/login",
|
|
json={"username": "alice", "password": "demo-password"},
|
|
)
|
|
assert login_response.status_code == 200
|
|
token = login_response.json()["data"]["access_token"]
|
|
|
|
me_response = client.get(
|
|
"/api/demo/identity/me",
|
|
headers={"Authorization": f"Bearer {token}"},
|
|
)
|
|
assert me_response.status_code == 200
|
|
assert me_response.json()["data"]["user_name"] == "alice"
|
|
|
|
deploy_response = client.post(
|
|
"/api/demo/software-a/deploy-tasks",
|
|
json={
|
|
"operator": {"user_id": "u1001", "user_name": "alice"},
|
|
"tenant_id": "tenant-demo",
|
|
"app_code": "order-service",
|
|
"env": "test",
|
|
"version": "1.2.3",
|
|
"target_nodes": ["10.0.0.12"],
|
|
"deploy_options": {"graceful": True},
|
|
},
|
|
)
|
|
assert deploy_response.status_code == 200
|
|
software_a_task_id = deploy_response.json()["data"]["software_a_task_id"]
|
|
|
|
query_response = client.get(f"/api/demo/software-a/deploy-tasks/{software_a_task_id}")
|
|
assert query_response.status_code == 200
|
|
assert query_response.json()["data"]["task_status"] == "SUCCEEDED"
|
|
|
|
|
|
def test_edge_heartbeat_pull_and_report_flow() -> None:
|
|
with TestClient(app) as client:
|
|
heartbeat_response = client.post(
|
|
"/api/agent/edge/heartbeat",
|
|
json={
|
|
"edge_id": "edge-shanghai-001",
|
|
"hostname": "customer-host-01",
|
|
"os_type": "WINDOWS",
|
|
"agent_version": "0.1.0",
|
|
"capabilities": ["http_health_check"],
|
|
},
|
|
)
|
|
assert heartbeat_response.status_code == 200
|
|
assert heartbeat_response.json()["data"]["node_status"] == "ONLINE"
|
|
|
|
create_response = client.post(
|
|
"/api/agent/tasks",
|
|
json={
|
|
"input_text": "deploy order-service 1.2.3 to test",
|
|
"channel": "WEB",
|
|
"session_id": "sess-003",
|
|
"tenant_id": "tenant-demo",
|
|
"context": {},
|
|
},
|
|
)
|
|
task_id = create_response.json()["data"]["task_id"]
|
|
|
|
confirm_response = client.post(
|
|
f"/api/agent/tasks/{task_id}/confirm",
|
|
json={"confirmed": True, "comment": "confirm"},
|
|
)
|
|
assert confirm_response.status_code == 200
|
|
|
|
pull_response = client.post(
|
|
"/api/agent/edge/tasks/pull",
|
|
json={"edge_id": "edge-shanghai-001", "max_tasks": 5},
|
|
)
|
|
assert pull_response.status_code == 200
|
|
tasks = pull_response.json()["data"]["tasks"]
|
|
matched_tasks = [item for item in tasks if item["task_id"] == task_id]
|
|
assert len(matched_tasks) == 1
|
|
step_id = matched_tasks[0]["step_id"]
|
|
assert matched_tasks[0]["tool_name"] == "http_health_check"
|
|
|
|
report_response = client.post(
|
|
"/api/agent/edge/tasks/report",
|
|
json={
|
|
"edge_id": "edge-shanghai-001",
|
|
"task_id": task_id,
|
|
"step_id": step_id,
|
|
"tool_name": "http_health_check",
|
|
"success": True,
|
|
"code": "OK",
|
|
"message": "200 OK",
|
|
"data": {"status_code": 200, "latency_ms": 45},
|
|
"evidence": {"response_body": "{\"status\":\"UP\"}"},
|
|
"started_at": "2026-04-08 20:20:00.000",
|
|
"finished_at": "2026-04-08 20:20:00.100",
|
|
},
|
|
)
|
|
assert report_response.status_code == 200
|
|
assert report_response.json()["data"]["task_status"] == "SUCCEEDED"
|
|
|
|
get_response = client.get(f"/api/agent/tasks/{task_id}")
|
|
assert get_response.status_code == 200
|
|
assert get_response.json()["data"]["task_status"] == "SUCCEEDED"
|
|
assert get_response.json()["data"]["software_a_task_id"] is not None
|
|
assert get_response.json()["data"]["software_a_task_status"] == "SUCCEEDED"
|
|
assert get_response.json()["data"]["verification_result"]["http_ok"] is True
|
|
|
|
|
|
def test_edge_event_report_endpoint() -> None:
|
|
with TestClient(app) as client:
|
|
event_response = client.post(
|
|
"/api/agent/edge/events",
|
|
json={
|
|
"edge_id": "edge-shanghai-001",
|
|
"event_type": "AGENT_EXCEPTION",
|
|
"message": "executor timeout",
|
|
"detail": {"tool_name": "http_health_check", "timeout_ms": 3000},
|
|
},
|
|
)
|
|
assert event_response.status_code == 200
|
|
assert event_response.json()["data"]["accepted"] is True
|
|
assert event_response.json()["data"]["event_type"] == "AGENT_EXCEPTION"
|
|
|
|
|
|
def test_task_report_contains_traces() -> None:
|
|
with TestClient(app) as client:
|
|
client.post(
|
|
"/api/agent/edge/heartbeat",
|
|
json={
|
|
"edge_id": "edge-shanghai-001",
|
|
"hostname": "customer-host-01",
|
|
"os_type": "WINDOWS",
|
|
"agent_version": "0.1.0",
|
|
"capabilities": ["http_health_check"],
|
|
},
|
|
)
|
|
|
|
create_response = client.post(
|
|
"/api/agent/tasks",
|
|
headers={"X-Request-Id": "req-report-create-001"},
|
|
json={
|
|
"input_text": "deploy order-service 1.2.3 to test",
|
|
"channel": "WEB",
|
|
"session_id": "sess-004",
|
|
"tenant_id": "tenant-demo",
|
|
"context": {},
|
|
},
|
|
)
|
|
task_id = create_response.json()["data"]["task_id"]
|
|
|
|
client.post(
|
|
f"/api/agent/tasks/{task_id}/confirm",
|
|
headers={"X-Request-Id": "req-report-confirm-001"},
|
|
json={"confirmed": True, "comment": "confirm"},
|
|
)
|
|
pull_response = client.post(
|
|
"/api/agent/edge/tasks/pull",
|
|
json={"edge_id": "edge-shanghai-001", "max_tasks": 5},
|
|
)
|
|
step = [item for item in pull_response.json()["data"]["tasks"] if item["task_id"] == task_id][0]
|
|
client.post(
|
|
"/api/agent/edge/tasks/report",
|
|
json={
|
|
"edge_id": "edge-shanghai-001",
|
|
"task_id": task_id,
|
|
"step_id": step["step_id"],
|
|
"tool_name": step["tool_name"],
|
|
"success": True,
|
|
"code": "OK",
|
|
"message": "200 OK",
|
|
"data": {"status_code": 200},
|
|
"evidence": {"response_body": "{\"status\":\"UP\"}"},
|
|
"started_at": "2026-04-08 20:20:00.000",
|
|
"finished_at": "2026-04-08 20:20:00.100",
|
|
},
|
|
)
|
|
|
|
report_response = client.get(f"/api/agent/tasks/{task_id}/report")
|
|
assert report_response.status_code == 200
|
|
payload = report_response.json()["data"]
|
|
assert payload["task_basic"]["task_id"] == task_id
|
|
assert len(payload["tool_trace"]) >= 2
|
|
assert len(payload["verification_trace"]) >= 1
|
|
assert len(payload["audit_trace"]) >= 3
|
|
assert payload["approval_trace"] == []
|
|
assert any(item["request_id"] == "req-report-confirm-001" for item in payload["tool_trace"])
|
|
assert any(item["operator_user_name"] == "alice" for item in payload["tool_trace"])
|
|
assert any(item["request_id"] == "req-report-create-001" for item in payload["audit_trace"])
|
|
|
|
|
|
def test_cancel_running_task() -> None:
|
|
with TestClient(app) as client:
|
|
create_response = client.post(
|
|
"/api/agent/tasks",
|
|
json={
|
|
"input_text": "deploy order-service 1.2.3 to test",
|
|
"channel": "WEB",
|
|
"session_id": "sess-005",
|
|
"tenant_id": "tenant-demo",
|
|
"context": {},
|
|
},
|
|
)
|
|
task_id = create_response.json()["data"]["task_id"]
|
|
client.post(
|
|
f"/api/agent/tasks/{task_id}/confirm",
|
|
json={"confirmed": True, "comment": "confirm"},
|
|
)
|
|
|
|
cancel_response = client.post(
|
|
f"/api/agent/tasks/{task_id}/cancel",
|
|
json={"reason": "manual stop"},
|
|
)
|
|
assert cancel_response.status_code == 200
|
|
assert cancel_response.json()["data"]["task_status"] == "CANCELLED"
|
|
assert cancel_response.json()["data"]["software_a_task_status"] == "CANCELLED"
|
|
|
|
get_response = client.get(f"/api/agent/tasks/{task_id}")
|
|
assert get_response.status_code == 200
|
|
assert get_response.json()["data"]["task_status"] == "CANCELLED"
|
|
|
|
|
|
def test_confirm_twice_returns_conflict() -> None:
|
|
with TestClient(app) as client:
|
|
create_response = client.post(
|
|
"/api/agent/tasks",
|
|
json={
|
|
"input_text": "deploy order-service 1.2.3 to test",
|
|
"channel": "WEB",
|
|
"session_id": "sess-006",
|
|
"tenant_id": "tenant-demo",
|
|
"context": {},
|
|
},
|
|
)
|
|
task_id = create_response.json()["data"]["task_id"]
|
|
|
|
first_confirm = client.post(
|
|
f"/api/agent/tasks/{task_id}/confirm",
|
|
json={"confirmed": True, "comment": "confirm"},
|
|
)
|
|
assert first_confirm.status_code == 200
|
|
|
|
second_confirm = client.post(
|
|
f"/api/agent/tasks/{task_id}/confirm",
|
|
json={"confirmed": True, "comment": "confirm again"},
|
|
)
|
|
assert second_confirm.status_code == 409
|
|
assert second_confirm.json()["code"] == "CONFLICT"
|
|
|
|
|
|
def test_approval_decision_conflicts_after_task_cancelled() -> None:
|
|
with TestClient(app) as client:
|
|
create_response = client.post(
|
|
"/api/agent/tasks",
|
|
json={
|
|
"input_text": "deploy order-service 1.2.3 to prod",
|
|
"channel": "WEB",
|
|
"session_id": "sess-007",
|
|
"tenant_id": "tenant-demo",
|
|
"context": {},
|
|
},
|
|
)
|
|
task_id = create_response.json()["data"]["task_id"]
|
|
|
|
confirm_response = client.post(
|
|
f"/api/agent/tasks/{task_id}/confirm",
|
|
json={"confirmed": True, "comment": "need approval"},
|
|
)
|
|
approval_id = confirm_response.json()["data"]["approval_id"]
|
|
|
|
cancel_response = client.post(
|
|
f"/api/agent/tasks/{task_id}/cancel",
|
|
json={"reason": "manual stop before approval"},
|
|
)
|
|
assert cancel_response.status_code == 200
|
|
assert cancel_response.json()["data"]["task_status"] == "CANCELLED"
|
|
|
|
decision_response = client.post(
|
|
f"/api/demo/approval/requests/{approval_id}/decision",
|
|
json={
|
|
"decision": "APPROVED",
|
|
"comment": "approved too late",
|
|
"operator": {"user_id": "u2001", "user_name": "bob"},
|
|
},
|
|
)
|
|
assert decision_response.status_code == 409
|
|
assert decision_response.json()["code"] == "CONFLICT"
|
|
|
|
|
|
def test_duplicate_edge_report_returns_conflict() -> None:
|
|
with TestClient(app) as client:
|
|
client.post(
|
|
"/api/agent/edge/heartbeat",
|
|
json={
|
|
"edge_id": "edge-shanghai-001",
|
|
"hostname": "customer-host-01",
|
|
"os_type": "WINDOWS",
|
|
"agent_version": "0.1.0",
|
|
"capabilities": ["http_health_check"],
|
|
},
|
|
)
|
|
create_response = client.post(
|
|
"/api/agent/tasks",
|
|
json={
|
|
"input_text": "deploy order-service 1.2.3 to test",
|
|
"channel": "WEB",
|
|
"session_id": "sess-008",
|
|
"tenant_id": "tenant-demo",
|
|
"context": {},
|
|
},
|
|
)
|
|
task_id = create_response.json()["data"]["task_id"]
|
|
client.post(
|
|
f"/api/agent/tasks/{task_id}/confirm",
|
|
json={"confirmed": True, "comment": "confirm"},
|
|
)
|
|
|
|
pull_response = client.post(
|
|
"/api/agent/edge/tasks/pull",
|
|
json={"edge_id": "edge-shanghai-001", "max_tasks": 5},
|
|
)
|
|
step = [item for item in pull_response.json()["data"]["tasks"] if item["task_id"] == task_id][0]
|
|
|
|
first_report = client.post(
|
|
"/api/agent/edge/tasks/report",
|
|
json={
|
|
"edge_id": "edge-shanghai-001",
|
|
"task_id": task_id,
|
|
"step_id": step["step_id"],
|
|
"tool_name": step["tool_name"],
|
|
"success": True,
|
|
"code": "OK",
|
|
"message": "200 OK",
|
|
"data": {"status_code": 200},
|
|
"evidence": {"response_body": "{\"status\":\"UP\"}"},
|
|
"started_at": "2026-04-08 20:20:00.000",
|
|
"finished_at": "2026-04-08 20:20:00.100",
|
|
},
|
|
)
|
|
assert first_report.status_code == 200
|
|
|
|
second_report = client.post(
|
|
"/api/agent/edge/tasks/report",
|
|
json={
|
|
"edge_id": "edge-shanghai-001",
|
|
"task_id": task_id,
|
|
"step_id": step["step_id"],
|
|
"tool_name": step["tool_name"],
|
|
"success": True,
|
|
"code": "OK",
|
|
"message": "200 OK",
|
|
"data": {"status_code": 200},
|
|
"evidence": {"response_body": "{\"status\":\"UP\"}"},
|
|
"started_at": "2026-04-08 20:20:00.000",
|
|
"finished_at": "2026-04-08 20:20:00.100",
|
|
},
|
|
)
|
|
assert second_report.status_code == 409
|
|
assert second_report.json()["code"] == "CONFLICT"
|
|
|
|
|
|
def test_task_fails_when_software_a_deploy_fails() -> None:
|
|
with TestClient(app) as client:
|
|
create_response = client.post(
|
|
"/api/agent/tasks",
|
|
json={
|
|
"input_text": "deploy fail-service 1.2.3-fail to test",
|
|
"channel": "WEB",
|
|
"session_id": "sess-009",
|
|
"tenant_id": "tenant-demo",
|
|
"context": {},
|
|
},
|
|
)
|
|
assert create_response.status_code == 200
|
|
task_id = create_response.json()["data"]["task_id"]
|
|
|
|
confirm_response = client.post(
|
|
f"/api/agent/tasks/{task_id}/confirm",
|
|
json={"confirmed": True, "comment": "confirm"},
|
|
)
|
|
assert confirm_response.status_code == 200
|
|
assert confirm_response.json()["data"]["task_status"] == "FAILED"
|
|
assert confirm_response.json()["data"]["software_a_task_status"] == "FAILED"
|
|
|
|
get_response = client.get(f"/api/agent/tasks/{task_id}")
|
|
assert get_response.status_code == 200
|
|
assert get_response.json()["data"]["task_status"] == "FAILED"
|
|
assert get_response.json()["data"]["software_a_task_status"] == "FAILED"
|
|
|
|
pull_response = client.post(
|
|
"/api/agent/edge/tasks/pull",
|
|
json={"edge_id": "edge-shanghai-001", "max_tasks": 10},
|
|
)
|
|
assert pull_response.status_code == 200
|
|
assert all(item["task_id"] != task_id for item in pull_response.json()["data"]["tasks"])
|
|
|
|
|
|
def test_demo_software_a_endpoint_can_return_failed_task() -> None:
|
|
with TestClient(app) as client:
|
|
deploy_response = client.post(
|
|
"/api/demo/software-a/deploy-tasks",
|
|
json={
|
|
"operator": {"user_id": "u1001", "user_name": "alice"},
|
|
"tenant_id": "tenant-demo",
|
|
"app_code": "fail-service",
|
|
"env": "test",
|
|
"version": "1.2.3-fail",
|
|
"target_nodes": ["10.0.0.12"],
|
|
"deploy_options": {"graceful": True},
|
|
},
|
|
)
|
|
assert deploy_response.status_code == 200
|
|
assert deploy_response.json()["data"]["task_status"] == "FAILED"
|
|
software_a_task_id = deploy_response.json()["data"]["software_a_task_id"]
|
|
|
|
query_response = client.get(f"/api/demo/software-a/deploy-tasks/{software_a_task_id}")
|
|
assert query_response.status_code == 200
|
|
assert query_response.json()["data"]["task_status"] == "FAILED"
|
|
assert query_response.json()["data"]["error_detail"] is not None
|
|
|
|
|
|
def test_high_risk_task_can_be_rejected() -> None:
|
|
with TestClient(app) as client:
|
|
create_response = client.post(
|
|
"/api/agent/tasks",
|
|
json={
|
|
"input_text": "deploy order-service 1.2.3 to prod",
|
|
"channel": "WEB",
|
|
"session_id": "sess-010",
|
|
"tenant_id": "tenant-demo",
|
|
"context": {},
|
|
},
|
|
)
|
|
task_id = create_response.json()["data"]["task_id"]
|
|
|
|
confirm_response = client.post(
|
|
f"/api/agent/tasks/{task_id}/confirm",
|
|
json={"confirmed": True, "comment": "need approval"},
|
|
)
|
|
approval_id = confirm_response.json()["data"]["approval_id"]
|
|
|
|
decision_response = client.post(
|
|
f"/api/demo/approval/requests/{approval_id}/decision",
|
|
json={
|
|
"decision": "REJECTED",
|
|
"comment": "rejected",
|
|
"operator": {"user_id": "u2001", "user_name": "bob"},
|
|
},
|
|
)
|
|
assert decision_response.status_code == 200
|
|
assert decision_response.json()["data"]["approval_status"] == "REJECTED"
|
|
|
|
get_task_response = client.get(f"/api/agent/tasks/{task_id}")
|
|
assert get_task_response.status_code == 200
|
|
assert get_task_response.json()["data"]["task_status"] == "CANCELLED"
|
|
assert get_task_response.json()["data"]["approval_status"] == "REJECTED"
|
|
|
|
|
|
def test_edge_failure_marks_task_failed() -> None:
|
|
with TestClient(app) as client:
|
|
client.post(
|
|
"/api/agent/edge/heartbeat",
|
|
json={
|
|
"edge_id": "edge-shanghai-001",
|
|
"hostname": "customer-host-01",
|
|
"os_type": "WINDOWS",
|
|
"agent_version": "0.1.0",
|
|
"capabilities": ["http_health_check"],
|
|
},
|
|
)
|
|
create_response = client.post(
|
|
"/api/agent/tasks",
|
|
json={
|
|
"input_text": "deploy order-service 1.2.3 to test",
|
|
"channel": "WEB",
|
|
"session_id": "sess-011",
|
|
"tenant_id": "tenant-demo",
|
|
"context": {},
|
|
},
|
|
)
|
|
task_id = create_response.json()["data"]["task_id"]
|
|
client.post(
|
|
f"/api/agent/tasks/{task_id}/confirm",
|
|
json={"confirmed": True, "comment": "confirm"},
|
|
)
|
|
pull_response = client.post(
|
|
"/api/agent/edge/tasks/pull",
|
|
json={"edge_id": "edge-shanghai-001", "max_tasks": 5},
|
|
)
|
|
step = [item for item in pull_response.json()["data"]["tasks"] if item["task_id"] == task_id][0]
|
|
|
|
report_response = client.post(
|
|
"/api/agent/edge/tasks/report",
|
|
json={
|
|
"edge_id": "edge-shanghai-001",
|
|
"task_id": task_id,
|
|
"step_id": step["step_id"],
|
|
"tool_name": step["tool_name"],
|
|
"success": False,
|
|
"code": "HTTP_500",
|
|
"message": "health check failed",
|
|
"data": {"status_code": 500},
|
|
"evidence": {"response_body": "{\"status\":\"DOWN\"}"},
|
|
"started_at": "2026-04-08 20:20:00.000",
|
|
"finished_at": "2026-04-08 20:20:00.100",
|
|
},
|
|
)
|
|
assert report_response.status_code == 200
|
|
assert report_response.json()["data"]["task_status"] == "FAILED"
|
|
|
|
get_response = client.get(f"/api/agent/tasks/{task_id}")
|
|
assert get_response.status_code == 200
|
|
assert get_response.json()["data"]["task_status"] == "FAILED"
|
|
assert get_response.json()["data"]["verification_result"]["http_ok"] is False
|