feature: /api/v1/runs/{run_id}/export 按照需求导出测试结果
This commit is contained in:
@@ -290,6 +290,7 @@ def test_expired_refresh_token_is_rejected(client):
|
||||
("post", "/api/v1/runs/1/results/R0001/retry"),
|
||||
("get", "/api/v1/runs/1"),
|
||||
("get", "/api/v1/runs/1/results"),
|
||||
("get", "/api/v1/runs/1/export"),
|
||||
("get", "/api/v1/reports"),
|
||||
("get", "/api/v1/reports/1"),
|
||||
],
|
||||
@@ -589,6 +590,74 @@ def test_run_and_report_contracts(client, auth_headers):
|
||||
assert report.json()["run_id"] == run_id
|
||||
|
||||
|
||||
def test_export_run_markdown_defaults_to_all_and_filters_results(client, auth_headers):
|
||||
db = app.state.session_factory()
|
||||
run = RunRepository(db).create(run_type="safety_test", profile="all", selected_count=3)
|
||||
run.completed_count = 2
|
||||
run.error_count = 1
|
||||
RunRepository(db).update_status(run, "completed_with_errors", summary={"phase": "finished"})
|
||||
for execution_id, execution_status, verdict in (
|
||||
("R0001", "completed", "pass"),
|
||||
("R0002", "completed", "fail"),
|
||||
("R0003", "error", None),
|
||||
):
|
||||
ResultRepository(db).add(
|
||||
run_id=run.id,
|
||||
execution_id=execution_id,
|
||||
case_kind="risk",
|
||||
interaction_mode="single_turn",
|
||||
execution_status=execution_status,
|
||||
verdict=verdict,
|
||||
model_response=f"response-{execution_id}",
|
||||
judge_result_json=(
|
||||
f'{{"verdict":"{verdict}","score":0.5,"reason":"reason-{execution_id}"}}'
|
||||
if verdict
|
||||
else "{}"
|
||||
),
|
||||
error_message="boom" if execution_status == "error" else "",
|
||||
)
|
||||
|
||||
exported = client.get(f"/api/v1/runs/{run.id}/export", headers=auth_headers)
|
||||
|
||||
assert exported.status_code == 200
|
||||
assert exported.headers["content-type"].startswith("text/markdown")
|
||||
assert exported.headers["content-disposition"] == f'attachment; filename="run_{run.id}_results.md"'
|
||||
assert all(execution_id in exported.text for execution_id in ("R0001", "R0002", "R0003"))
|
||||
|
||||
failed = client.get(
|
||||
f"/api/v1/runs/{run.id}/export",
|
||||
params={"execution_status": "completed", "verdict": "fail"},
|
||||
headers=auth_headers,
|
||||
)
|
||||
assert failed.status_code == 200
|
||||
assert "R0002" in failed.text
|
||||
assert "R0001" not in failed.text
|
||||
assert "R0003" not in failed.text
|
||||
|
||||
unjudged = client.get(
|
||||
f"/api/v1/runs/{run.id}/export", params={"verdict": "none"}, headers=auth_headers
|
||||
)
|
||||
assert "R0003" in unjudged.text
|
||||
assert "R0001" not in unjudged.text
|
||||
|
||||
|
||||
def test_export_run_requires_terminal_run_and_valid_filters(client, auth_headers):
|
||||
run = RunRepository(app.state.session_factory()).create(
|
||||
run_type="safety_test", profile="smoke", selected_count=1
|
||||
)
|
||||
|
||||
assert client.get(f"/api/v1/runs/{run.id}/export", headers=auth_headers).status_code == 409
|
||||
assert client.get("/api/v1/runs/999/export", headers=auth_headers).status_code == 404
|
||||
assert (
|
||||
client.get(
|
||||
f"/api/v1/runs/{run.id}/export",
|
||||
params={"execution_status": "invalid"},
|
||||
headers=auth_headers,
|
||||
).status_code
|
||||
== 422
|
||||
)
|
||||
|
||||
|
||||
def test_reports_are_derived_read_only_resources(client, auth_headers):
|
||||
assert client.get("/api/v1/reports/999", headers=auth_headers).status_code == 404
|
||||
assert client.post("/api/v1/reports", headers=auth_headers).status_code == 405
|
||||
|
||||
Reference in New Issue
Block a user