You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
orquestrador/tests/test_integration_service.py

137 lines
5.0 KiB
Python

import os
import unittest
from unittest.mock import AsyncMock, patch
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.pool import StaticPool
os.environ.setdefault("DEBUG", "false")
from app.db.mock_database import MockBase
from app.db.mock_models import IntegrationDelivery
from app.services.integrations.events import ORDER_CREATED_EVENT
from app.services.integrations import service as integration_service
class IntegrationServiceTests(unittest.IsolatedAsyncioTestCase):
def _build_session_local(self):
engine = create_engine(
"sqlite://",
connect_args={"check_same_thread": False},
poolclass=StaticPool,
)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
MockBase.metadata.create_all(bind=engine)
self.addCleanup(engine.dispose)
return SessionLocal
async def test_emit_business_event_creates_and_dispatches_delivery(self):
SessionLocal = self._build_session_local()
with patch.object(integration_service, "SessionMockLocal", SessionLocal), patch.object(
integration_service.settings,
"integrations_enabled",
True,
), patch.object(
integration_service.settings,
"integration_sync_delivery_enabled",
True,
), patch.object(
integration_service,
"_get_provider",
return_value=type(
"FakeProvider",
(),
{
"send_email": AsyncMock(return_value={"message_id": "brevo-123"}),
},
)(),
):
integration_service.upsert_email_integration_route(
event_type=ORDER_CREATED_EVENT,
recipient_email="ops@example.com",
)
deliveries = await integration_service.emit_business_event(
ORDER_CREATED_EVENT,
{
"numero_pedido": "PED-1",
"modelo_veiculo": "Fiat Argo 2024",
"valor_veiculo": 67739.0,
"status": "Ativo",
"status_veiculo": "Reservado",
},
)
self.assertEqual(len(deliveries), 1)
self.assertEqual(deliveries[0]["status"], "sent")
self.assertEqual(deliveries[0]["provider_message_id"], "brevo-123")
db = SessionLocal()
try:
stored = db.query(IntegrationDelivery).one()
self.assertEqual(stored.status, "sent")
self.assertEqual(stored.provider_message_id, "brevo-123")
finally:
db.close()
async def test_emit_business_event_deduplicates_by_route_and_payload(self):
SessionLocal = self._build_session_local()
with patch.object(integration_service, "SessionMockLocal", SessionLocal), patch.object(
integration_service.settings,
"integrations_enabled",
True,
), patch.object(
integration_service.settings,
"integration_sync_delivery_enabled",
False,
):
integration_service.upsert_email_integration_route(
event_type=ORDER_CREATED_EVENT,
recipient_email="ops@example.com",
)
await integration_service.emit_business_event(ORDER_CREATED_EVENT, {"numero_pedido": "PED-1"})
await integration_service.emit_business_event(ORDER_CREATED_EVENT, {"numero_pedido": "PED-1"})
db = SessionLocal()
try:
rows = db.query(IntegrationDelivery).all()
self.assertEqual(len(rows), 1)
self.assertEqual(rows[0].status, "pending")
finally:
db.close()
async def test_process_pending_deliveries_marks_failure_when_provider_fails(self):
SessionLocal = self._build_session_local()
with patch.object(integration_service, "SessionMockLocal", SessionLocal), patch.object(
integration_service.settings,
"integrations_enabled",
True,
), patch.object(
integration_service.settings,
"integration_sync_delivery_enabled",
False,
):
integration_service.upsert_email_integration_route(
event_type=ORDER_CREATED_EVENT,
recipient_email="ops@example.com",
)
await integration_service.emit_business_event(ORDER_CREATED_EVENT, {"numero_pedido": "PED-1"})
with patch.object(integration_service, "SessionMockLocal", SessionLocal), patch.object(
integration_service,
"_get_provider",
side_effect=integration_service.IntegrationProviderError("brevo offline"),
):
deliveries = await integration_service.process_pending_deliveries(limit=10)
self.assertEqual(len(deliveries), 1)
self.assertEqual(deliveries[0]["status"], "failed")
self.assertIn("brevo offline", deliveries[0]["last_error"])
if __name__ == "__main__":
unittest.main()