assistant/apps/server/tests/test_budget_closed.py

77 lines
4.6 KiB
Python

"""A confirmed worker close preserves partial validation but revokes readiness."""
from __future__ import annotations
import pytest
from apps.server.tests.test_discovery import item, search_candidate
from apps.server.tests.test_learning import client, initialize
from apps.server.tests.test_postgres import pg_client
from apps.server.tests.test_reading import NOTE_ID, TITLE, detail_output, learned_detail
@pytest.fixture(params=["client", "pg_client"])
def budget_client(request):
return request.getfixturevalue(request.param)
def test_budget_close_keeps_partial_evidence_revokes_ready_and_never_replays(budget_client):
client = budget_client
initialize(client)
_, search = search_candidate(client, [item(TITLE)])
run = client.post("/api/discovery/runs", json={"search_candidate_id": search["id"], "keyword": "准备装修"}).json()
task, candidate, _ = learned_detail(client, seek=True)
prefix = "/api/learning/tasks/" + task["id"]
endpoint = "/api/discovery/runs/" + run["id"] + "/readings"
payload = {"detail_candidate_id": candidate["id"], "note_id": NOTE_ID}
first = client.post(endpoint, json=payload).json()
assert first["status"] == "completed"
store = client.app_reference.state.store
old_candidate = store.one("SELECT digest,manifest_json FROM candidates WHERE id=$1", (candidate["id"],))
old_run = store.one("SELECT data_json FROM discovery_runs WHERE id=$1", (run["id"],))
old_reading = store.one("SELECT data_json FROM reading_runs WHERE id=$1", (first["id"],))
old_validation = store.one("SELECT data_json FROM validations WHERE id=$1", (first["validation_id"],))
worker = client.worker_reference
original = worker.call
flag = "true"
async def timeout_with_partial(method, params):
value = await original(method, params)
if method == "verify" and params.get("note_binding"):
value.update(passed=False, outputs={"note_detail": value["outputs"]["note_detail"]}, errors=["验证预算已到,保留已完成输出"], error_codes=["VERIFY_BUDGET"], session_closed=flag)
if flag is True:
worker.sessions.pop(params["task_id"], None) # Simulate actual context close.
return value
worker.call = timeout_with_partial
# Only an actual boolean close acknowledgment can invalidate the session.
malformed = client.post(endpoint, json=payload).json()
assert malformed["status"] == "partial"
before_close = client.get(prefix).json()
assert before_close["browser_readiness"]["ready"] is True
flag = True
response = client.post(endpoint, json=payload)
assert response.status_code == 201, response.text
partial = response.json()
assert partial["status"] == "partial" and partial["detail"] == detail_output() and partial["comments"] is None
assert partial["validation_id"] and partial["error_codes"] == ["VERIFY_BUDGET"]
assert partial["seek_results"][0]["target_reached"] is True
assert partial["evidence"] and all(client.get(item["screenshot_url"]).status_code == 200 for item in partial["evidence"])
task_after = client.get(prefix).json()
assert task_after["status"] == "paused" and task_after["browser_status"] == "closed"
assert task_after["browser_readiness"]["ready"] is False and task_after["browser_readiness"]["next_action"] == "open_browser"
validation = next(item for item in task_after["validations"] if item["id"] == partial["validation_id"])
assert validation["status"] == "failed" and validation["error_codes"] == ["VERIFY_BUDGET"]
assert validation["environment"]["browser_session_closed"] is True
assert validation["actual_outputs"]["note_detail"] == detail_output() and validation["evidence"] == partial["evidence"]
calls = len(worker.calls)
next_reading = client.post(endpoint, json=payload).json()
assert next_reading["status"] == "failed" and next_reading["validation_id"] is None
assert next_reading["error_codes"] == ["browser_session_required"] and next_reading["detail"] is None
assert worker.calls[calls:] == [] # No status/open/ready/verify or automatic retry.
assert client.get("/api/discovery/readings/" + partial["id"]).json() == partial
assert client.get("/api/discovery/readings/" + first["id"]).json() == first
assert store.one("SELECT digest,manifest_json FROM candidates WHERE id=$1", (candidate["id"],)) == old_candidate
assert store.one("SELECT data_json FROM discovery_runs WHERE id=$1", (run["id"],)) == old_run
assert store.one("SELECT data_json FROM reading_runs WHERE id=$1", (first["id"],)) == old_reading
assert store.one("SELECT data_json FROM validations WHERE id=$1", (first["validation_id"],)) == old_validation