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.
137 lines
5.0 KiB
Python
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()
|