import pytest from review_agent.file_summary.workflow import create_file_summary_batch, start_file_summary_workflow from review_agent.models import ( Conversation, FileAttachment, FileSummaryBatch, FileSummaryBatchAttachment, Message, WorkflowEvent, WorkflowNodeRun, ) from review_agent.services import stream_message pytestmark = pytest.mark.django_db def test_create_batch_binds_active_attachments_and_initializes_nodes(django_user_model): 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="自动汇总") active = FileAttachment.objects.create( conversation=conversation, user=user, original_name="a.docx", storage_path="x/a.docx", file_size=1, ) FileAttachment.objects.create( conversation=conversation, user=user, original_name="old.docx", is_active=False, storage_path="x/old.docx", file_size=1, ) batch = create_file_summary_batch(conversation=conversation, user=user, trigger_message=message) assert batch.status == FileSummaryBatch.Status.PENDING assert FileSummaryBatchAttachment.objects.get(batch=batch).attachment == active active.refresh_from_db() assert active.upload_status == FileAttachment.UploadStatus.BOUND assert WorkflowNodeRun.objects.filter(batch=batch).count() >= 6 assert WorkflowEvent.objects.filter(batch=batch, event_type="workflow_created").exists() def test_start_file_summary_workflow_runs_synchronously_for_tests(django_user_model): 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="自动汇总") FileAttachment.objects.create( conversation=conversation, user=user, original_name="a.docx", storage_path="x/a.docx", file_size=1, ) batch = create_file_summary_batch(conversation=conversation, user=user, trigger_message=message) start_file_summary_workflow(batch, async_run=False) batch.refresh_from_db() assert batch.status == FileSummaryBatch.Status.SUCCESS assert WorkflowEvent.objects.filter(batch=batch, event_type="workflow_completed").exists() def test_stream_message_returns_workflow_meta_when_triggered(settings, django_user_model): settings.FILE_SUMMARY_ASYNC = False user = django_user_model.objects.create_user(username="owner", password="pass") conversation = Conversation.objects.create(user=user, title="会话") FileAttachment.objects.create( conversation=conversation, user=user, original_name="a.docx", storage_path="x/a.docx", file_size=1, ) frames = list(stream_message(conversation, "请自动汇总文件目录与页数")) joined = "".join(frames) assert "workflow_started" in joined assert "\"workflow_type\": \"file_summary\"" in joined assert FileSummaryBatch.objects.filter(conversation=conversation).exists() def test_stream_message_uses_normal_llm_path_when_not_triggered(monkeypatch, django_user_model): user = django_user_model.objects.create_user(username="owner", password="pass") conversation = Conversation.objects.create(user=user, title="会话") def fake_stream_reply(conversation, content): yield "普通回复" monkeypatch.setattr("review_agent.services.stream_reply", fake_stream_reply) frames = list(stream_message(conversation, "你好")) joined = "".join(frames) assert "普通回复" in joined assert "workflow_started" not in joined