Files
DEMO-AGENT/tests/test_application_form_fill_workflow.py

196 lines
7.3 KiB
Python

import pytest
from review_agent.application_form_fill.constants import FORM_FILL_NODE_DEFINITIONS
from review_agent.application_form_fill.workflow import (
create_application_form_fill_batch,
find_latest_successful_summary_batch,
start_application_form_fill_workflow,
)
from review_agent.models import (
ApplicationFormFillBatch,
Conversation,
FileAttachment,
FileSummaryBatch,
Message,
WorkflowEvent,
WorkflowNodeRun,
)
from review_agent.services import stream_message
from review_agent.skill_router import SkillRoute
pytestmark = pytest.mark.django_db
def test_find_latest_successful_summary_batch_ignores_failed_batches(django_user_model):
user = django_user_model.objects.create_user(username="owner", password="pass")
conversation = Conversation.objects.create(user=user, title="会话")
success = FileSummaryBatch.objects.create(
conversation=conversation,
user=user,
batch_no="FS-AFF-OK",
status=FileSummaryBatch.Status.SUCCESS,
)
FileSummaryBatch.objects.create(
conversation=conversation,
user=user,
batch_no="FS-AFF-FAILED",
status=FileSummaryBatch.Status.FAILED,
)
assert find_latest_successful_summary_batch(conversation) == success
def test_create_application_form_fill_batch_initializes_nodes(settings, tmp_path, django_user_model):
settings.MEDIA_ROOT = tmp_path
user = django_user_model.objects.create_user(username="owner", password="pass")
conversation = Conversation.objects.create(user=user, title="会话")
message = Message.objects.create(conversation=conversation, role=Message.Role.USER, content="帮我填注册证")
summary = FileSummaryBatch.objects.create(
conversation=conversation,
user=user,
batch_no="FS-AFF-OK",
status=FileSummaryBatch.Status.SUCCESS,
)
batch = create_application_form_fill_batch(
conversation=conversation,
user=user,
trigger_message=message,
source_summary_batch=summary,
)
assert batch.status == ApplicationFormFillBatch.Status.PENDING
assert batch.output_types == ["word", "excel", "json"]
assert WorkflowNodeRun.objects.filter(
workflow_type="application_form_fill",
workflow_batch_id=batch.pk,
).count() == len(FORM_FILL_NODE_DEFINITIONS)
assert WorkflowEvent.objects.filter(
workflow_type="application_form_fill",
workflow_batch_id=batch.pk,
event_type="workflow_created",
).exists()
def test_application_form_fill_executor_runs_nodes_and_skips_pdf(settings, tmp_path, django_user_model):
settings.MEDIA_ROOT = tmp_path
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-AFF-OK",
status=FileSummaryBatch.Status.SUCCESS,
)
batch = create_application_form_fill_batch(
conversation=conversation,
user=user,
source_summary_batch=summary,
)
start_application_form_fill_workflow(batch, async_run=False)
batch.refresh_from_db()
assert batch.status == ApplicationFormFillBatch.Status.SUCCESS
assert WorkflowNodeRun.objects.get(
workflow_type="application_form_fill",
workflow_batch_id=batch.pk,
node_code="pdf_convert",
).status == WorkflowNodeRun.Status.SKIPPED
assert WorkflowEvent.objects.filter(
workflow_type="application_form_fill",
workflow_batch_id=batch.pk,
event_type="workflow_completed",
).exists()
def test_stream_message_prompts_for_upload_when_no_summary_or_attachment(monkeypatch, django_user_model):
user = django_user_model.objects.create_user(username="owner", password="pass")
conversation = Conversation.objects.create(user=user, title="会话")
monkeypatch.setattr(
"review_agent.services.route_message_intent",
lambda conversation, content: SkillRoute(
action="application_form_fill",
workflow_type="application_form_fill",
confidence=0.9,
),
)
frames = list(stream_message(conversation, "帮我填注册证"))
joined = "".join(frames)
assert "请先在当前对话右侧上传需要填表的产品资料或压缩包" in joined
assert not ApplicationFormFillBatch.objects.exists()
def test_stream_message_starts_application_form_fill_workflow(monkeypatch, settings, tmp_path, django_user_model):
settings.MEDIA_ROOT = tmp_path
settings.APPLICATION_FORM_FILL_ASYNC = False
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-AFF-OK",
status=FileSummaryBatch.Status.SUCCESS,
)
monkeypatch.setattr(
"review_agent.services.route_message_intent",
lambda conversation, content: SkillRoute(
action="application_form_fill",
workflow_type="application_form_fill",
confidence=0.9,
),
)
frames = list(stream_message(conversation, "帮我填注册证"))
joined = "".join(frames)
assert "workflow_started" in joined
assert '"workflow_type": "application_form_fill"' in joined
assert "已启动申报文件自动填表工作流" in joined
assert ApplicationFormFillBatch.objects.filter(conversation=conversation).exists()
def test_stream_message_auto_runs_summary_before_application_form_fill(
monkeypatch, settings, tmp_path, django_user_model
):
settings.MEDIA_ROOT = tmp_path
settings.APPLICATION_FORM_FILL_ASYNC = False
user = django_user_model.objects.create_user(username="owner", password="pass")
conversation = Conversation.objects.create(user=user, title="会话")
attachment_path = tmp_path / "application.txt"
attachment_path.write_text("产品名称:甲胎蛋白检测试剂盒", encoding="utf-8")
FileAttachment.objects.create(
conversation=conversation,
user=user,
original_name="application.txt",
storage_path=str(attachment_path),
file_size=attachment_path.stat().st_size,
is_active=True,
)
monkeypatch.setattr(
"review_agent.services.route_message_intent",
lambda conversation, content: SkillRoute(
action="application_form_fill",
workflow_type="application_form_fill",
confidence=0.9,
),
)
def finish_summary(batch, async_run=True):
batch.status = FileSummaryBatch.Status.SUCCESS
batch.save(update_fields=["status"])
monkeypatch.setattr("review_agent.services.start_file_summary_workflow", finish_summary)
frames = list(stream_message(conversation, "为我该方案生成申报模板"))
joined = "".join(frames)
assert '"workflow_type": "file_summary"' in joined
assert '"workflow_type": "application_form_fill"' in joined
assert "汇总完成后继续自动填表" in joined
assert FileSummaryBatch.objects.filter(conversation=conversation, status=FileSummaryBatch.Status.SUCCESS).exists()
assert ApplicationFormFillBatch.objects.filter(conversation=conversation).exists()