"""Tests for NotificationManagerService.""" from unittest.mock import AsyncMock, Mock import pytest from capa_de_integracion.config import Settings from capa_de_integracion.models.notification import ExternalNotificationRequest from capa_de_integracion.services.dlp_service import DLPService from capa_de_integracion.services.firestore_service import FirestoreService from capa_de_integracion.services.notification_manager import NotificationManagerService from capa_de_integracion.services.redis_service import RedisService @pytest.fixture def mock_settings(): """Create mock settings.""" settings = Mock(spec=Settings) settings.dlp_template_complete_flow = "test-template" return settings @pytest.fixture def mock_redis(): """Create mock Redis service.""" redis = Mock(spec=RedisService) redis.save_or_append_notification = AsyncMock() return redis @pytest.fixture def mock_firestore(): """Create mock Firestore service.""" firestore = Mock(spec=FirestoreService) firestore.save_or_append_notification = AsyncMock() return firestore @pytest.fixture def mock_dlp(): """Create mock DLP service.""" dlp = Mock(spec=DLPService) dlp.get_obfuscated_string = AsyncMock(return_value="Obfuscated text") return dlp @pytest.fixture def service(mock_settings, mock_redis, mock_firestore, mock_dlp): """Create NotificationManagerService instance.""" return NotificationManagerService( settings=mock_settings, redis_service=mock_redis, firestore_service=mock_firestore, dlp_service=mock_dlp, ) @pytest.mark.asyncio async def test_process_notification_basic(service, mock_redis, mock_dlp): """Test basic notification processing.""" request = ExternalNotificationRequest( telefono="555-1234", texto="Your card was blocked", parametros_ocultos=None, ) await service.process_notification(request) # Verify DLP was called mock_dlp.get_obfuscated_string.assert_called_once_with( "Your card was blocked", "test-template", ) # Verify Redis save was called mock_redis.save_or_append_notification.assert_called_once() call_args = mock_redis.save_or_append_notification.call_args notification = call_args[0][0] assert notification.telefono == "555-1234" assert notification.texto == "Obfuscated text" assert notification.status == "active" assert notification.nombre_evento_dialogflow == "notificacion" @pytest.mark.asyncio async def test_process_notification_with_parameters(service, mock_redis, mock_dlp): """Test notification processing with hidden parameters.""" request = ExternalNotificationRequest( telefono="555-1234", texto="Transaction alert", parametros_ocultos={ "amount": "100.00", "merchant": "Store ABC", }, ) await service.process_notification(request) # Verify Redis save was called mock_redis.save_or_append_notification.assert_called_once() notification = mock_redis.save_or_append_notification.call_args[0][0] # Verify parameters have prefix assert "notification_po_amount" in notification.parametros assert notification.parametros["notification_po_amount"] == "100.00" assert "notification_po_merchant" in notification.parametros assert notification.parametros["notification_po_merchant"] == "Store ABC" @pytest.mark.asyncio async def test_process_notification_firestore_async(service, mock_redis, mock_firestore): """Test that Firestore save is asynchronous (fire-and-forget).""" request = ExternalNotificationRequest( telefono="555-1234", texto="Test notification", parametros_ocultos=None, ) await service.process_notification(request) # Redis should be called immediately mock_redis.save_or_append_notification.assert_called_once() # Firestore may or may not be called yet (it's async) # We can't easily test the fire-and-forget behavior without waiting @pytest.mark.asyncio async def test_process_notification_empty_parameters(service, mock_redis): """Test notification processing with empty parameters.""" request = ExternalNotificationRequest( telefono="555-1234", texto="Test", parametros_ocultos={}, ) await service.process_notification(request) notification = mock_redis.save_or_append_notification.call_args[0][0] assert notification.parametros == {} @pytest.mark.asyncio async def test_process_notification_generates_unique_id(service, mock_redis): """Test that each notification gets a unique ID.""" request = ExternalNotificationRequest( telefono="555-1234", texto="Test", parametros_ocultos=None, ) await service.process_notification(request) notification1 = mock_redis.save_or_append_notification.call_args[0][0] await service.process_notification(request) notification2 = mock_redis.save_or_append_notification.call_args[0][0] assert notification1.id_notificacion != notification2.id_notificacion