100 lines
3.3 KiB
Python
100 lines
3.3 KiB
Python
from contextlib import nullcontext
|
|
from pathlib import Path
|
|
|
|
import app.communication_service as service
|
|
|
|
|
|
class _Result:
|
|
def __init__(self, *, scalar_value=None, rows=()):
|
|
self.scalar_value = scalar_value
|
|
self.rows = list(rows)
|
|
|
|
def scalar(self):
|
|
return self.scalar_value
|
|
|
|
def mappings(self):
|
|
return self
|
|
|
|
def all(self):
|
|
return self.rows
|
|
|
|
|
|
class _Connection:
|
|
def __init__(self, *, possible, rows=()):
|
|
self.possible = possible
|
|
self.rows = rows
|
|
self.statements = []
|
|
|
|
def execute(self, statement, params=None):
|
|
self.statements.append((str(statement), params))
|
|
if len(self.statements) == 1:
|
|
return _Result(scalar_value=self.possible)
|
|
return _Result(rows=self.rows)
|
|
|
|
|
|
class _Engine:
|
|
def __init__(self, connection):
|
|
self.connection = connection
|
|
|
|
def begin(self):
|
|
return nullcontext(self.connection)
|
|
|
|
|
|
def test_no_historical_candidates_returns_after_one_statement(monkeypatch):
|
|
connection = _Connection(possible=False)
|
|
monkeypatch.setattr(service, "engine", _Engine(connection))
|
|
|
|
assert service._list_message_backed_chatwoot_items_for_opportunity(
|
|
"dc3c020e-33eb-4067-b7da-ab684533a425"
|
|
) == []
|
|
assert len(connection.statements) == 1
|
|
assert "SELECT EXISTS" in connection.statements[0][0]
|
|
|
|
|
|
def test_positive_fallback_uses_two_statements_and_preserves_rows(monkeypatch):
|
|
expected = [{"id": "message-1", "source_system": "chatwoot", "created_at": "2026-08-14"}]
|
|
connection = _Connection(possible=True, rows=expected)
|
|
monkeypatch.setattr(service, "engine", _Engine(connection))
|
|
|
|
result = service._list_message_backed_chatwoot_items_for_opportunity(
|
|
"dc3c020e-33eb-4067-b7da-ab684533a425", limit=12
|
|
)
|
|
|
|
assert result == expected
|
|
assert len(connection.statements) == 2
|
|
assert connection.statements[1][1]["limit"] == 12
|
|
|
|
|
|
def test_relationship_paths_are_unioned_without_or_join_conditions(monkeypatch):
|
|
connection = _Connection(possible=True)
|
|
monkeypatch.setattr(service, "engine", _Engine(connection))
|
|
service._list_message_backed_chatwoot_items_for_opportunity(
|
|
"dc3c020e-33eb-4067-b7da-ab684533a425"
|
|
)
|
|
sql = connection.statements[1][0]
|
|
|
|
assert "re.id = m.raw_event_id OR re.message_id = m.id" not in sql
|
|
assert "ar.message_id = m.id OR ar.raw_event_id = re.id" not in sql
|
|
assert "t.message_id = m.id OR t.raw_event_id = re.id" not in sql
|
|
assert sql.count(" UNION\n") >= 10
|
|
assert "SELECT DISTINCT ON (m.id)" in sql
|
|
assert "ORDER BY m.id, COALESCE(t.created_at, m.created_at) DESC" in sql
|
|
assert "ORDER BY created_at DESC" in sql
|
|
|
|
|
|
def test_only_missing_relationship_indexes_are_added():
|
|
migration = Path("migrations/008_historical_communication_lookup_indexes.sql").read_text()
|
|
expected = {
|
|
"messages(raw_event_id)",
|
|
"raw_events(message_id)",
|
|
"action_runs(message_id)",
|
|
"action_runs(raw_event_id)",
|
|
"tasks(message_id)",
|
|
"tasks(raw_event_id)",
|
|
"tasks(action_run_id)",
|
|
}
|
|
assert all(columns in migration for columns in expected)
|
|
assert "messages(conversation_id)" not in migration
|
|
assert "raw_events(conversation_id)" not in migration
|
|
assert "tasks(opportunity_id)" not in migration
|