PMFlow/backend/tests/test_feishu_receive_orchest...

119 lines
4.7 KiB
Python

import pytest
from app.services.integrations.feishu_integration_service.service import FeishuIntegrationService
@pytest.mark.asyncio
async def test_handle_message_receive_ignores_bot_sender() -> None:
service = FeishuIntegrationService(db=object())
result = await service._handle_message_receive(
{
"message": {"message_id": "m-bot"},
"sender": {"sender_type": "bot"},
"chat": {"chat_id": "c1"},
}
)
assert result["code"] == 0
assert result["msg"] == "Ignore bot/app message"
@pytest.mark.asyncio
async def test_handle_message_receive_routes_empty_text_branch(monkeypatch) -> None:
service = FeishuIntegrationService(db=object())
called: dict[str, object] = {}
def _fake_build_receive_context(*, event, state_trace_id): # noqa: ARG001
return {
"ingress_source": "feishu",
"message": {"message_id": "m-empty", "message_type": "post"},
"sender": {"sender_name": "测试用户"},
"message_id": "m-empty",
"sender_type": "user",
"raw_message_content": "",
"message_content": "",
"chat_id": "chat-empty",
"mentioned_bot_names": ["PMFlow"],
"sender_open_id": "ou-empty",
"perf_t0": None,
}
async def _fake_record_ingress_trace(**kwargs):
called["trace"] = kwargs
async def _fake_reply_for_empty_text_ingress(**kwargs):
called["empty_reply"] = kwargs
return True
monkeypatch.setattr(service, "_build_receive_context", _fake_build_receive_context)
monkeypatch.setattr(service, "_record_ingress_trace", _fake_record_ingress_trace)
monkeypatch.setattr(service, "_reply_for_empty_text_ingress", _fake_reply_for_empty_text_ingress)
result = await service._handle_message_receive({"type": "im.message.receive_v1"})
assert result["code"] == 0
assert result["msg"] == "No text content"
assert called["trace"]["message_id"] == "m-empty"
assert called["empty_reply"]["chat_id"] == "chat-empty"
@pytest.mark.asyncio
async def test_handle_message_receive_orchestrates_capture_and_finalize(monkeypatch) -> None:
service = FeishuIntegrationService(db=object())
called: dict[str, object] = {}
def _fake_build_receive_context(*, event, state_trace_id): # noqa: ARG001
return {
"ingress_source": "long_connection",
"message": {"message_id": "m-1", "message_type": "text"},
"sender": {"sender_name": "原始用户名"},
"sender_id": {"open_id": "ou-1"},
"message_id": "m-1",
"sender_type": "user",
"raw_message_content": "hello",
"message_content": "hello",
"chat_id": "chat-1",
"chat_type": "group",
"captured_at": None,
"mentioned_bot_names": [],
"sender_open_id": "ou-1",
"perf_t0": 1.2,
"message_attachments": [],
"occurred_at_iso": None,
}
async def _fake_record_ingress_trace(**kwargs):
called["trace"] = kwargs
async def _fake_resolve_sender_display_name(*, sender, sender_id): # noqa: ARG001
return "解析后用户名"
def _fake_normalize_message_attachments_from_context(*, context): # noqa: ARG001
return []
async def _fake_capture_and_persist_from_ingress(**kwargs):
called["capture"] = kwargs
return {
"status": "captured",
"classification": "signal",
"linked_project_ids": [11],
"auto_tasks": [],
"ai_trace_id": "trace-1",
}
async def _fake_finalize_receive_result(**kwargs):
called["finalize"] = kwargs
return {"code": 0, "msg": "success", "data": {"scene": "execute"}}
monkeypatch.setattr(service, "_build_receive_context", _fake_build_receive_context)
monkeypatch.setattr(service, "_record_ingress_trace", _fake_record_ingress_trace)
monkeypatch.setattr(service, "_resolve_sender_display_name", _fake_resolve_sender_display_name)
monkeypatch.setattr(service, "_normalize_message_attachments_from_context", _fake_normalize_message_attachments_from_context)
monkeypatch.setattr(service, "_capture_and_persist_from_ingress", _fake_capture_and_persist_from_ingress)
monkeypatch.setattr(service, "_finalize_receive_result", _fake_finalize_receive_result)
result = await service._handle_message_receive({"type": "im.message.receive_v1"})
assert result["code"] == 0
assert result["data"]["scene"] == "execute"
assert called["capture"]["chat_id"] == "chat-1"
assert called["capture"]["sender_name"] == "解析后用户名"
assert called["finalize"]["chat_type"] == "group"