"""Unit tests for EventBridge connector.""" import json from unittest.mock import MagicMock import pytest from botocore.exceptions import ClientError from src.connectors.eventbridge import EventBridgeConnector from src.errors import TransientError from src.schemas import EventBridgeEventMetadata @pytest.fixture def mock_boto_client(): """Mock boto3 client.""" return MagicMock() @pytest.fixture def eb_connector(mock_boto_client): """EventBridge connector instance.""" return EventBridgeConnector('test.source', mock_boto_client) @pytest.fixture def sample_metadata(): """Sample metadata.""" return EventBridgeEventMetadata( correlation_id='corr-123', outbox_event_id=123, target_id=456, target_type='test_entity', created_at='2023-01-01T10:00:00+00:00', processed_at='2023-01-01T10:30:00+00:00', ) class TestEventBridgeConnector: """Test EventBridgeConnector.""" def test_put_event_success(self, eb_connector, mock_boto_client, sample_metadata): """Test successful put_event.""" mock_boto_client.put_events.return_value = {'FailedEntryCount': 0} eb_connector.put_event( detail_type='test.type', metadata=sample_metadata, data={'foo': 'bar'}, ) mock_boto_client.put_events.assert_called_once() entries = mock_boto_client.put_events.call_args.kwargs['Entries'] assert len(entries) == 1 assert entries[0]['Source'] == 'test.source' assert entries[0]['DetailType'] == 'test.type' detail = json.loads(entries[0]['Detail']) assert detail['data'] == {'foo': 'bar'} assert detail['metadata']['correlation_id'] == 'corr-123' assert detail['metadata']['outbox_event_id'] == 123 def test_put_event_data_none(self, eb_connector, mock_boto_client, sample_metadata): """Test put_event when data is None.""" mock_boto_client.put_events.return_value = {'FailedEntryCount': 0} eb_connector.put_event( detail_type='test.type', metadata=sample_metadata, data=None, ) mock_boto_client.put_events.assert_called_once() entries = mock_boto_client.put_events.call_args.kwargs['Entries'] detail = json.loads(entries[0]['Detail']) assert detail['data'] is None assert detail['metadata']['correlation_id'] == 'corr-123' def test_put_event_partial_failure( self, eb_connector, mock_boto_client, sample_metadata ): """Test put_event where API returns success but entry failed.""" mock_boto_client.put_events.return_value = { 'FailedEntryCount': 1, 'Entries': [{'ErrorCode': 'Throttling', 'ErrorMessage': 'Busy'}], } with pytest.raises(TransientError, match='Failed to publish event'): eb_connector.put_event('test.type', sample_metadata, {}) def test_put_event_client_error( self, eb_connector, mock_boto_client, sample_metadata ): """Test put_event raising ClientError.""" mock_boto_client.put_events.side_effect = ClientError( {'Error': {'Code': 'InternalException', 'Message': 'Error'}}, 'PutEvents' ) with pytest.raises(TransientError, match='EventBridge error'): eb_connector.put_event('test.type', sample_metadata, {})