handoff fixes
This commit is contained in:
parent
83f0eba64d
commit
8653f319f7
9 changed files with 30 additions and 1309 deletions
|
|
@ -1,125 +1,13 @@
|
|||
import pytest
|
||||
from bson import ObjectId
|
||||
|
||||
from app.services.human_handoff_service import (
|
||||
MESSAGE_SCOPE_EXTERNAL,
|
||||
MESSAGE_SCOPE_HANDOFF,
|
||||
resolve_handoff_from_inbound,
|
||||
)
|
||||
from app.services.human_handoff_service import MESSAGE_SCOPE_EXTERNAL, MESSAGE_SCOPE_HANDOFF
|
||||
|
||||
|
||||
class FakeCollection:
|
||||
def __init__(self, documents=None):
|
||||
self.documents = list(documents or [])
|
||||
|
||||
async def find_one(self, query):
|
||||
for document in self.documents:
|
||||
if all(document.get(key) == value for key, value in query.items()):
|
||||
return document
|
||||
if "$ne" in query.get("status", {}):
|
||||
if document.get("status") == query["status"]["$ne"]:
|
||||
continue
|
||||
for document in self.documents:
|
||||
matches = True
|
||||
for key, value in query.items():
|
||||
if key == "status" and isinstance(value, dict) and "$ne" in value:
|
||||
if document.get("status") == value["$ne"]:
|
||||
matches = False
|
||||
break
|
||||
elif document.get(key) != value:
|
||||
matches = False
|
||||
break
|
||||
if matches:
|
||||
return document
|
||||
return None
|
||||
|
||||
def find(self, query):
|
||||
class Cursor:
|
||||
def __init__(self, items):
|
||||
self.items = items
|
||||
|
||||
async def to_list(self, length):
|
||||
return self.items[:length]
|
||||
|
||||
filtered = [
|
||||
document
|
||||
for document in self.documents
|
||||
if all(document.get(key) == value for key, value in query.items())
|
||||
]
|
||||
return Cursor(filtered)
|
||||
|
||||
|
||||
class FakeDatabase:
|
||||
def __init__(self):
|
||||
self.human_handoff_rules = FakeCollection()
|
||||
self.messages = FakeCollection()
|
||||
self.mailbox_entries = FakeCollection()
|
||||
self.human_handoffs = FakeCollection()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_resolve_handoff_requires_owner_and_thread_context():
|
||||
database = FakeDatabase()
|
||||
handoff_thread_id = ObjectId()
|
||||
message_id = ObjectId()
|
||||
database.human_handoff_rules.documents = [
|
||||
{
|
||||
"account_id": "acct-1",
|
||||
"owner_email": "owner@gmail.com",
|
||||
"active": True,
|
||||
}
|
||||
]
|
||||
database.messages.documents = [
|
||||
{
|
||||
"_id": message_id,
|
||||
"message_id": "<handoff-1@gentic.email>",
|
||||
"message_id_folded": "<handoff-1@gentic.email>",
|
||||
"message_scope": MESSAGE_SCOPE_HANDOFF,
|
||||
}
|
||||
]
|
||||
database.mailbox_entries.documents = [
|
||||
{
|
||||
"account_id": "acct-1",
|
||||
"message_id": message_id,
|
||||
"thread_id": handoff_thread_id,
|
||||
"message_scope": MESSAGE_SCOPE_HANDOFF,
|
||||
}
|
||||
]
|
||||
database.human_handoffs.documents = [
|
||||
{
|
||||
"_id": ObjectId(),
|
||||
"account_id": "acct-1",
|
||||
"handoff_thread_id": handoff_thread_id,
|
||||
"human_email": "owner@gmail.com",
|
||||
"status": "WAITING_FOR_HUMAN",
|
||||
}
|
||||
]
|
||||
|
||||
handoff = await resolve_handoff_from_inbound(
|
||||
database,
|
||||
account_id="acct-1",
|
||||
agent_email="support@gentic.email",
|
||||
sender_address="owner@gmail.com",
|
||||
in_reply_to="<handoff-1@gentic.email>",
|
||||
references=[],
|
||||
)
|
||||
assert handoff is not None
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_resolve_handoff_rejects_unknown_sender():
|
||||
database = FakeDatabase()
|
||||
handoff = await resolve_handoff_from_inbound(
|
||||
database,
|
||||
account_id="acct-1",
|
||||
agent_email="support@gentic.email",
|
||||
sender_address="stranger@example.com",
|
||||
in_reply_to="<handoff-1@gentic.email>",
|
||||
references=[],
|
||||
)
|
||||
assert handoff is None
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_external_scope_constant_isolated_from_handoff():
|
||||
def test_scope_constants_are_distinct():
|
||||
assert MESSAGE_SCOPE_EXTERNAL != MESSAGE_SCOPE_HANDOFF
|
||||
|
||||
|
||||
def test_human_handoff_runtime_is_disabled():
|
||||
import app.services.human_handoff_service as module
|
||||
|
||||
assert not hasattr(module, "maybe_trigger_handoff")
|
||||
assert not hasattr(module, "process_human_reply")
|
||||
assert not hasattr(module, "resolve_handoff_from_inbound")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue