108 lines
4.0 KiB
Python
108 lines
4.0 KiB
Python
from contextlib import nullcontext
|
|
|
|
import pytest
|
|
|
|
import app.document_reconciliation_service as document_service
|
|
import app.operation_service as operation_service
|
|
import app.opportunity_next_action_service as service
|
|
from app.domain.opportunity_flow import build_opportunity_evidence
|
|
|
|
|
|
class _Result:
|
|
def __init__(self, rows):
|
|
self._rows = rows
|
|
|
|
def mappings(self):
|
|
return self
|
|
|
|
def all(self):
|
|
return self._rows
|
|
|
|
|
|
class _Connection:
|
|
def __init__(self, opportunities, *, tasks=None, operation_links=None):
|
|
self.opportunities = opportunities
|
|
self.tasks = tasks or []
|
|
self.operation_links = operation_links or []
|
|
self.query_count = 0
|
|
|
|
def execute(self, statement, params=None):
|
|
self.query_count += 1
|
|
sql = str(statement)
|
|
if "FROM opportunities WHERE" in sql:
|
|
wanted = set((params or {}).get("opportunity_ids", []))
|
|
return _Result([row for oid, row in self.opportunities.items() if oid in wanted])
|
|
if "FROM tasks WHERE" in sql:
|
|
return _Result(self.tasks)
|
|
if "FROM operation_links WHERE" in sql:
|
|
return _Result(self.operation_links)
|
|
return _Result([])
|
|
|
|
|
|
class _Engine:
|
|
def __init__(self, connection):
|
|
self.connection = connection
|
|
|
|
def begin(self):
|
|
return nullcontext(self.connection)
|
|
|
|
|
|
def _opportunity(oid):
|
|
return {
|
|
"id": oid,
|
|
"stage": "NEW_LEAD",
|
|
"status": "open",
|
|
"title": "Teste",
|
|
"fiscal_customer_id": None,
|
|
"customer_id": None,
|
|
"metadata": {},
|
|
}
|
|
|
|
|
|
@pytest.mark.parametrize("tasks,operation_links", [
|
|
([], []),
|
|
([{"id": "task-1", "opportunity_id": "11111111-1111-1111-1111-111111111111",
|
|
"action_code": "CONTACT_CUSTOMER", "action": "Contactar cliente", "note": "",
|
|
"priority": "alta", "route": "/tasks/task-1", "status": "pending",
|
|
"due_at": None, "created_at": None, "metadata": {}, "rn": 1}], []),
|
|
([], [{"id": "link-1", "opportunity_id": "11111111-1111-1111-1111-111111111111",
|
|
"system": "clientflow", "external_type": "payment", "external_id": None,
|
|
"external_name": "Pagamento", "external_url": None, "status": "confirmed",
|
|
"payload": {}, "last_synced_at": None, "created_at": None, "updated_at": None}]),
|
|
])
|
|
def test_bulk_decision_is_equivalent_to_individual(monkeypatch, tasks, operation_links):
|
|
oid = "11111111-1111-1111-1111-111111111111"
|
|
row = _opportunity(oid)
|
|
connection = _Connection({oid: row}, tasks=tasks, operation_links=operation_links)
|
|
monkeypatch.setattr(service, "engine", _Engine(connection))
|
|
monkeypatch.setattr(operation_service, "ensure_operation_schema", lambda: None)
|
|
monkeypatch.setattr(document_service, "document_reconciliation_v2_available", lambda conn=None: False)
|
|
|
|
snapshots = service._bulk_operation_snapshots([oid], {oid: operation_links}, {oid: []})
|
|
evidence = build_opportunity_evidence(
|
|
row, linked_documents=[], tasks=tasks, operation_snapshot=snapshots[oid],
|
|
linked_customer=None, fiscal_data_complete=False,
|
|
has_reconciliation_candidate=False, company_profile="blif",
|
|
)
|
|
monkeypatch.setattr(service, "_build_db_evidence", lambda opportunity_id: evidence)
|
|
|
|
assert service.get_opportunity_next_actions([oid])[oid] == service.get_opportunity_next_action(oid)
|
|
|
|
|
|
def test_bulk_query_count_is_constant_for_batch_size(monkeypatch):
|
|
monkeypatch.setattr(operation_service, "ensure_operation_schema", lambda: None)
|
|
monkeypatch.setattr(document_service, "document_reconciliation_v2_available", lambda conn=None: False)
|
|
|
|
def measured(size):
|
|
opportunities = {
|
|
f"00000000-0000-0000-0000-{number:012d}":
|
|
_opportunity(f"00000000-0000-0000-0000-{number:012d}")
|
|
for number in range(1, size + 1)
|
|
}
|
|
connection = _Connection(opportunities)
|
|
monkeypatch.setattr(service, "engine", _Engine(connection))
|
|
service.get_opportunity_next_actions(opportunities)
|
|
return connection.query_count
|
|
|
|
assert measured(1) == measured(50) == 6
|