feat(application-form-fill): 展示自动填表工作流卡片

This commit is contained in:
2026-06-07 18:43:39 +08:00
parent 9be10ef990
commit 4ac9c04dbf
7 changed files with 335 additions and 5 deletions

View File

@@ -0,0 +1,48 @@
import pytest
from django.urls import reverse
from review_agent.models import ApplicationFormFillBatch, Conversation, FileSummaryBatch, WorkflowNodeRun
pytestmark = pytest.mark.django_db
def test_workspace_renders_application_form_fill_workflow_card(client, django_user_model):
user = django_user_model.objects.create_user(username="owner", password="pass")
conversation = Conversation.objects.create(user=user, title="会话")
summary = FileSummaryBatch.objects.create(conversation=conversation, user=user, batch_no="FS-CARD")
batch = ApplicationFormFillBatch.objects.create(
conversation=conversation,
user=user,
source_summary_batch=summary,
batch_no="AFF-CARD",
status=ApplicationFormFillBatch.Status.PARTIAL_SUCCESS,
selected_templates=["registration_certificate"],
risk_notes=[{"type": "pdf_pending"}],
)
WorkflowNodeRun.objects.create(
workflow_type="application_form_fill",
workflow_batch_id=batch.pk,
node_group="form_fill",
node_code="word_fill",
node_name="填写 Word",
status=WorkflowNodeRun.Status.SUCCESS,
progress=100,
)
client.force_login(user)
response = client.get(f"{reverse('home')}?conversation={conversation.pk}")
content = response.content.decode("utf-8")
assert "AFF-CARD" in content
assert 'data-workflow-type="application_form_fill"' in content
assert "填写 Word" in content
assert "data-application-form-fill-status-url-template" in content
def test_frontend_selects_application_form_fill_status_url_and_terminal_status():
script = open("static/js/app.js", encoding="utf-8").read()
assert 'workflow_type === "application_form_fill"' in script
assert "data-application-form-fill-status-url-template" in script
assert 'status === "partial_success"' in script

View File

@@ -0,0 +1,113 @@
import json
import pytest
from django.urls import reverse
from review_agent.application_form_fill.constants import FORM_FILL_NODE_DEFINITIONS
from review_agent.models import (
ApplicationFormFillBatch,
Conversation,
ExportedSummaryFile,
FileSummaryBatch,
WorkflowNodeRun,
)
pytestmark = pytest.mark.django_db
def test_application_form_fill_start_requires_conversation_owner(client, monkeypatch, django_user_model):
owner = django_user_model.objects.create_user(username="owner", password="pass")
other = django_user_model.objects.create_user(username="other", password="pass")
conversation = Conversation.objects.create(user=owner, title="会话")
FileSummaryBatch.objects.create(
conversation=conversation,
user=owner,
batch_no="FS-VIEW",
status=FileSummaryBatch.Status.SUCCESS,
)
monkeypatch.setattr("review_agent.application_form_fill.views.start_application_form_fill_workflow", lambda batch, async_run=True: None)
client.force_login(other)
response = client.post(
reverse("application_form_fill_start"),
data=json.dumps({"conversation_id": conversation.pk}),
content_type="application/json",
)
assert response.status_code == 404
def test_application_form_fill_start_creates_batch(client, monkeypatch, django_user_model):
user = django_user_model.objects.create_user(username="owner", password="pass")
conversation = Conversation.objects.create(user=user, title="会话")
FileSummaryBatch.objects.create(
conversation=conversation,
user=user,
batch_no="FS-VIEW-OK",
status=FileSummaryBatch.Status.SUCCESS,
)
monkeypatch.setattr("review_agent.application_form_fill.views.start_application_form_fill_workflow", lambda batch, async_run=True: None)
client.force_login(user)
response = client.post(
reverse("application_form_fill_start"),
data=json.dumps({"conversation_id": conversation.pk, "template_codes": ["registration_certificate"]}),
content_type="application/json",
)
assert response.status_code == 200
payload = response.json()
assert payload["workflow_type"] == "application_form_fill"
assert ApplicationFormFillBatch.objects.filter(conversation=conversation).exists()
def test_application_form_fill_status_requires_owner_and_returns_nodes_exports(client, tmp_path, django_user_model):
owner = django_user_model.objects.create_user(username="owner", password="pass")
other = django_user_model.objects.create_user(username="other", password="pass")
conversation = Conversation.objects.create(user=owner, title="会话")
summary = FileSummaryBatch.objects.create(conversation=conversation, user=owner, batch_no="FS-STATUS")
batch = ApplicationFormFillBatch.objects.create(
conversation=conversation,
user=owner,
source_summary_batch=summary,
batch_no="AFF-STATUS",
status=ApplicationFormFillBatch.Status.PARTIAL_SUCCESS,
selected_templates=["registration_certificate"],
conflict_summary=[{"field_key": "product_name"}],
risk_notes=[{"type": "pdf_pending"}],
)
WorkflowNodeRun.objects.create(
workflow_type="application_form_fill",
workflow_batch_id=batch.pk,
node_group="form_fill",
node_code=FORM_FILL_NODE_DEFINITIONS[0][0],
node_name=FORM_FILL_NODE_DEFINITIONS[0][1],
status=WorkflowNodeRun.Status.SUCCESS,
progress=100,
)
output = tmp_path / "filled.docx"
output.write_bytes(b"word")
exported = ExportedSummaryFile.objects.create(
batch=summary,
workflow_type="application_form_fill",
workflow_batch_id=batch.pk,
export_category="filled_template",
export_type=ExportedSummaryFile.ExportType.WORD,
file_name="filled.docx",
storage_path=str(output),
)
client.force_login(other)
denied = client.get(reverse("application_form_fill_batch_status", args=[batch.pk]))
assert denied.status_code == 404
client.force_login(owner)
allowed = client.get(reverse("application_form_fill_batch_status", args=[batch.pk]))
assert allowed.status_code == 200
payload = allowed.json()
assert payload["batch"]["workflow_type"] == "application_form_fill"
assert payload["batch"]["status"] == ApplicationFormFillBatch.Status.PARTIAL_SUCCESS
assert payload["batch"]["conflict_count"] == 1
assert payload["nodes"][0]["node_code"] == "prepare"
assert payload["exports"][0]["id"] == exported.pk