feat: show progress while preparing batch archives

This commit is contained in:
chenmingxuan committed 2026-09-30 00:04:16 +08:00
1 parent 868f611c36
commit 8dbe054a8c
8 files changed
+333 -7

No files matched your search

@@ -3,6 +3,7 @@
from io import BytesIO
import json
import sqlite3
import threading
import time
from unittest.mock import AsyncMock, Mock
from uuid import UUID
@@ -108,6 +109,63 @@ def test_invalid_archive_and_empty_template():
assert not task_import.parse_workbook(task_import.template())["valid"]
def test_batch_archive_preparation_reports_progress_and_reuses_ready_file(
client, isolated, monkeypatch
):
batch = service.create_batch(payload())
batch_id = batch["id"]
started = threading.Event()
release = threading.Event()
calls = []
def slow_export(identifier, progress=None):
calls.append(identifier)
progress(0, 2, "正在打包任务 1/2")
started.set()
assert release.wait(5)
progress(2, 2, "正在完成压缩包")
path = reports.EXPORT_ROOT / "batches" / identifier / "批次报告.zip"
path.parent.mkdir(parents=True, exist_ok=True)
path.write_bytes(b"prepared archive")
return path
monkeypatch.setattr(reports, "export_batch", slow_export)
base = f"/api/automation/batches/{batch_id}/archive"
try:
response = client.post(base + "/prepare")
assert response.status_code == 200
assert response.json()["status"] == "preparing"
assert started.wait(2)
progress = client.get(base + "/status").json()
assert progress["total"] == 2
assert progress["stage"] == "正在打包任务 1/2"
assert client.get(base).status_code == 409
finally:
release.set()
for _ in range(50):
if client.get(base + "/status").json()["status"] == "ready":
break
time.sleep(0.02)
assert client.get(base + "/status").json()["status"] == "ready"
assert client.get(base).content == b"prepared archive"
assert calls == [batch_id]
def test_completed_batch_reuses_existing_archive(client, isolated, monkeypatch):
batch = service.create_batch(payload())
batch_id = batch["id"]
isolated.put("batch", batch_id, {**batch, "status": "completed", "report_ready": True})
path = reports.EXPORT_ROOT / "batches" / batch_id / "批次报告.zip"
path.parent.mkdir(parents=True)
path.write_bytes(b"existing archive")
exporter = Mock(side_effect=AssertionError("archive must not be rebuilt"))
monkeypatch.setattr(reports, "export_batch", exporter)
base = f"/api/automation/batches/{batch_id}/archive"
assert client.post(base + "/prepare").json()["status"] == "ready"
assert client.get(base).content == b"existing archive"
exporter.assert_not_called()
def test_preview_does_not_enqueue(client, isolated):
response = client.post(
"/api/automation/import/preview",