Files
DEMO-AGENT/tests/test_regulatory_frontend.py

266 lines
10 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import pytest
from django.urls import reverse
from review_agent.models import (
Conversation,
FileSummaryBatch,
FileSummaryItem,
RegulatoryArtifact,
RegulatoryNotificationRecord,
RegulatoryReviewBatch,
WorkflowNotificationRecord,
WorkflowNodeRun,
)
pytestmark = pytest.mark.django_db
def test_workspace_renders_regulatory_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-OK",
status=FileSummaryBatch.Status.SUCCESS,
)
regulatory = RegulatoryReviewBatch.objects.create(
conversation=conversation,
user=user,
source_summary_batch=summary,
batch_no="RR-CARD",
status=RegulatoryReviewBatch.Status.SUCCESS,
risk_summary={"blocking": 1, "high": 1},
)
WorkflowNodeRun.objects.create(
workflow_type="regulatory_review",
workflow_batch_id=regulatory.pk,
node_group="regulatory_review",
node_code="risk_assess",
node_name="风险评估",
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 "RR-CARD" in content
assert 'data-workflow-type="regulatory_review"' in content
assert "阻断项 1" in content
assert "风险评估" in content
assert "data-regulatory-status-url-template" in content
def test_workspace_renders_condition_confirmation_form(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-OK",
status=FileSummaryBatch.Status.SUCCESS,
)
regulatory = RegulatoryReviewBatch.objects.create(
conversation=conversation,
user=user,
source_summary_batch=summary,
batch_no="RR-WAIT",
status=RegulatoryReviewBatch.Status.WAITING_USER,
condition_json={
"confirmed": False,
"candidates": {
"product_category": {
"label": "产品类别",
"input_type": "select",
"options": ["体外诊断试剂", "医疗器械", "其他"],
"suggested": "体外诊断试剂",
},
"product_name": {
"label": "产品名称",
"input_type": "text",
"suggested": "甲胎蛋白检测试剂盒",
},
},
},
)
WorkflowNodeRun.objects.create(
workflow_type="regulatory_review",
workflow_batch_id=regulatory.pk,
node_group="condition_confirm",
node_code="condition_confirm",
node_name="适用条件确认",
status=WorkflowNodeRun.Status.WAITING_USER,
progress=50,
)
client.force_login(user)
response = client.get(f"{reverse('home')}?conversation={conversation.pk}")
content = response.content.decode("utf-8")
assert "适用条件确认" in content
assert "data-condition-confirm-form" in content
assert "体外诊断试剂" in content
assert "甲胎蛋白检测试剂盒" in content
form_index = content.index("data-condition-confirm-form")
summary_index = content.index('id="summaryPanel"')
assert form_index < summary_index
assert "data-condition-confirm-form" not in content[summary_index:]
def test_workspace_refreshes_incomplete_condition_confirmation_candidates(client, 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-OK",
status=FileSummaryBatch.Status.SUCCESS,
product_name="第1章 监管信息",
)
application = tmp_path / "application.txt"
application.write_text(
"卡尤迪生物科技宜兴有限公司申请境内第三类体外诊断试剂"
"呼吸道合胞病毒、肺炎支原体核酸检测试剂盒荧光PCR法产品注册。",
encoding="utf-8",
)
FileSummaryItem.objects.create(
batch=summary,
file_index=1,
directory_level="第1章 监管信息",
file_name="符合标准的清单.txt",
file_type="txt",
relative_path="第1章 监管信息/符合标准的清单.txt",
storage_path=str(application),
)
RegulatoryReviewBatch.objects.create(
conversation=conversation,
user=user,
source_summary_batch=summary,
batch_no="RR-WAIT-EMPTY",
status=RegulatoryReviewBatch.Status.WAITING_USER,
condition_json={
"confirmed": False,
"candidates": {
"product_category": {"label": "产品类别", "input_type": "select", "options": ["其他"], "suggested": "其他"},
"product_name": {"label": "产品名称", "input_type": "text", "suggested": ""},
},
},
)
client.force_login(user)
response = client.get(f"{reverse('home')}?conversation={conversation.pk}")
content = response.content.decode("utf-8")
assert "体外诊断试剂" in content
assert "呼吸道合胞病毒、肺炎支原体核酸检测试剂盒荧光PCR法" in content
def test_workspace_renders_rectification_actions_and_summaries(client, tmp_path, 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-OK",
status=FileSummaryBatch.Status.SUCCESS,
)
regulatory = RegulatoryReviewBatch.objects.create(
conversation=conversation,
user=user,
source_summary_batch=summary,
batch_no="RR-RECTIFY",
status=RegulatoryReviewBatch.Status.SUCCESS,
)
record_path = tmp_path / "review_record.json"
record_path.write_text('{"items":[{"status":"review_passed"}]}', encoding="utf-8")
RegulatoryArtifact.objects.create(
batch=regulatory,
artifact_type=RegulatoryArtifact.ArtifactType.JSON,
name="review_record.json",
storage_path=str(record_path),
metadata={"artifact": "review_record"},
)
RegulatoryNotificationRecord.objects.create(
batch=regulatory,
channel=RegulatoryNotificationRecord.Channel.MOCK,
target="法规整改负责人",
status=RegulatoryNotificationRecord.Status.SENT,
payload={"title": "缺少申请表"},
)
client.force_login(user)
response = client.get(f"{reverse('home')}?conversation={conversation.pk}")
content = response.content.decode("utf-8")
assert "data-rectification-action=\"full-review\"" in content
assert "data-rectification-action=\"issue-review\"" in content
assert "通知 1" in content
assert "复核记录 1" in content
def test_frontend_selects_status_url_by_workflow_type():
script = open("static/js/app.js", encoding="utf-8").read()
assert "workflow_type" in script
assert "data-regulatory-status-url-template" in script
assert "statusUrlForWorkflow" in script
assert "bindConditionConfirmForms" in script
assert "data-condition-confirm-form" in script
assert "ensureConditionConfirmationCard" in script
assert "condition_confirmation" in script
assert "bindRectificationActionButtons" in script
assert "data-rectification-action" in script
def test_frontend_polls_regulatory_workflow_with_explicit_workflow_type():
script = open("static/js/app.js", encoding="utf-8").read()
assert "function startWorkflowPolling(batchId, workflow_type)" in script
assert "startWorkflowPolling(payload.batch_id, payload.workflow_type)" in script
assert 'startWorkflowPolling(batchId, "regulatory_review")' in script
assert 'workflow_type || (card ? card.getAttribute("data-workflow-type") || "file_summary" : "file_summary")' in script
def test_frontend_keeps_single_condition_confirmation_prompt():
script = open("static/js/app.js", encoding="utf-8").read()
assert "data-condition-confirmation-card" in script
assert "removeStaleConditionConfirmationCards" in script
assert '[data-condition-confirmation-card]' in script
def test_regulatory_status_includes_failed_feishu_notification(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-RR")
batch = RegulatoryReviewBatch.objects.create(
conversation=conversation,
user=user,
source_summary_batch=summary,
batch_no="RR-FEISHU",
)
WorkflowNotificationRecord.objects.create(
workflow_type="regulatory_review",
workflow_batch_id=batch.pk,
workflow_batch_no=batch.batch_no,
workflow_status=batch.status,
dedupe_key=f"regulatory_review:{batch.pk}:{batch.status}",
trigger_user=user,
channel=WorkflowNotificationRecord.Channel.FEISHU_API,
target="负责人",
send_status=WorkflowNotificationRecord.SendStatus.FAILED,
message_title="法规核查完成",
error_message="bad receive_id",
)
client.force_login(user)
response = client.get(f"/api/review-agent/regulatory-review/{batch.pk}/status/")
payload = response.json()
assert payload["latest_notification"]["status_label"] == "飞书通知失败"
assert payload["latest_notification"]["error_message"] == "bad receive_id"