Files
AgentLab/backend/tests/test_workflow_restore.py
T
ThearchyHelios b418c0d951 最终验收:148 项逐条复核(原审查 142 条 + 平台问题 6 条),返工后 145 项解决
四组验收员拿审查原文在沙箱里逐条复现:133 项已解决、15 项部分解决、没有未解决或回退的;
另发现 10 个新问题。按归属返工后,剩 3 项低严重度:MCP / 自定义工具的危险标记(待用户拍板)、
选中环与运行态同色(需跨三处协调改)、「接着跑」这个说法是否更换(多处引用原文,暂留)。

这次返工改了
- 右栏:老运行没有 active_ms 时执行时长改按航迹算,不再显示最后一段的「22 ms」;循环出口行不再差一;
  取消在一轮中途时泳道脚注不写「0 ms」;分支、循环出口显示 case 的说明而不是 key;
  展开已完成轮次不再误报「N 条新进展」;旧数据里已完成的模型调用不再一律标成「已取消」
- 后端:跳过事件带节点名和类型;restore 版本时把已发布 / 受管退回草稿;只是打开旧会话不再把它顶到最前、
  标成「刚刚」;协作团队全程没有成员交付成果、调度者却判完成时按失败或降档处理,不再当成功交付
- 画布:循环体有「循环体 · 最多 N 轮」的底框,出口标签不再被自己的走线穿过;运行中校验角标退让;
  768 宽下工具栏不溢出;运行被拦时点名是哪个节点;正式运行弹层写明以谁的名义发起
- 问数据:离线时能力条不把「没取回来」说成 0;窄屏下会话列表收起;check-chat 在零点前后不再误报
- 公共层:FastAPI 422 校验错误翻成中文,不再把英文原文透给用户

验证(沙箱):tsc 干净,pytest 878 passed(两遍),check-all 15 项检查全绿。
2026-09-28 02:42:40 +08:00

63 lines
2.8 KiB
Python

"""恢复旧版本也是改图:受管 / 已发布得退回草稿。
status 说的是**当前画布**的状态。PATCH 改图时早就这么退了,restore 接口却只换图、
升版本、留快照,状态原样挂着——一张受管工作流恢复成从没过闸的旧图,工具栏照样
写「受管」。前端的版本历史为此绕开了它,但接口还对外开着,谁直接调都会中招。
已发布的那一版仍由 published_version 指着,正式运行不受影响。
"""
from __future__ import annotations
import pytest
from httpx import ASGITransport, AsyncClient
from app.db.base import SessionLocal
from app.db.models import Workflow
from app.main import app
def _graph(label: str) -> dict:
return {
"nodes": [
{"id": "start", "type": "input", "position": {"x": 0, "y": 0},
"data": {"label": "输入", "config": {"fields": [{"name": "q"}]}}},
{"id": "out", "type": "output", "position": {"x": 300, "y": 0},
"data": {"label": label, "config": {"fields": [{"name": "r", "value": "{{ input.q }}"}]}}},
],
"edges": [{"source": "start", "target": "out"}],
}
@pytest.fixture
async def client():
transport = ASGITransport(app=app)
async with AsyncClient(transport=transport, base_url="http://test") as c:
yield c
@pytest.mark.parametrize("level", ["published", "governed"])
async def test_restoring_an_old_version_drops_back_to_draft(client, level):
old, new = _graph("旧出口"), _graph("新出口")
workflow_id = (await client.post("/api/workflows", json={"name": "恢复", "graph": old})).json()["id"]
assert (await client.patch(f"/api/workflows/{workflow_id}", json={"graph": new})).status_code == 200
# 受管要过治理 lint,这里只关心恢复之后的状态,直接把 v2 立成发布版
async with SessionLocal() as session:
row = await session.get(Workflow, workflow_id)
row.status, row.published_version = level, 2
await session.commit()
r = await client.post(f"/api/workflows/{workflow_id}/versions/1/restore")
assert r.status_code == 200, r.text
body = r.json()
assert body["graph"] == old and body["version"] == 3
assert body["status"] == "draft", f"恢复成 v1 之后仍显示 {body['status']}"
assert body["published_version"] == 2, "发布的那一版不受影响"
assert (await client.get(f"/api/workflows/{workflow_id}")).json()["status"] == "draft"
async def test_restoring_a_draft_stays_a_draft(client):
workflow_id = (await client.post("/api/workflows", json={"name": "恢复", "graph": _graph("a")})).json()["id"]
await client.patch(f"/api/workflows/{workflow_id}", json={"graph": _graph("b")})
body = (await client.post(f"/api/workflows/{workflow_id}/versions/1/restore")).json()
assert body["status"] == "draft" and body["published_version"] is None