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()