import pytest from bson import ObjectId from app.services.thread_resolver import KnownMessage, resolve_thread_from_known def _known( internet_id: str, thread_id: ObjectId, *, references: list[str] | None = None, ) -> KnownMessage: from datetime import datetime, timezone from app.services.message_ids import normalize_message_id from app.services.subject_normalize import normalize_subject now = datetime.now(timezone.utc) return KnownMessage( id=ObjectId(), thread_id=thread_id, internet_message_id=normalize_message_id(internet_id) or "", account_id="acct-1", sent_at=now, received_at=now, created_at=now, participants=frozenset({"customer@gmail.com"}), normalized_subject=normalize_subject("lets try one more time"), ) def test_gmail_reply_to_gentic_resolves_same_thread(): thread_id = ObjectId() a1 = _known("", thread_id) g1 = _known("", thread_id, references=[""]) known = { a1.internet_message_id: a1, g1.internet_message_id: g1, } resolution = resolve_thread_from_known( account_id="acct-1", in_reply_to="", references=["", ""], subject="Re: lets try one more time", participants={"customer@gmail.com"}, known_by_internet_id=known, ) assert resolution.thread_id == thread_id assert resolution.thread_resolution_method == "in_reply_to" assert resolution.parent_message_id == g1.id @pytest.mark.asyncio async def test_lookup_known_messages_awaits_aggregate(): from app.services.thread_resolver import lookup_known_messages class FakeCursor: def __aiter__(self): return self async def __anext__(self): raise StopAsyncIteration class FakeMessages: def __init__(self): self.aggregate_awaited = False async def aggregate(self, pipeline): self.aggregate_awaited = True return FakeCursor() messages = FakeMessages() database = type("DB", (), {"messages": messages})() result = await lookup_known_messages(database, "acct-1", [""]) assert result == {} assert messages.aggregate_awaited is True