"""Lambda test module.""" from unittest.mock import Mock, patch import pytest from pydantic import ValidationError import app from file_upload_initialize.schemas import ProcessorResponse class TestHandler: """Tests for Lambda handler function.""" @patch('app.FileUploadInitializeProcessor') @patch('app.FileUploadEvent') def test_handler_success(self, mock_event_class, mock_processor_class): """Test successful handler execution.""" event_data = { 'detail': { 'bucket': {'name': 'test-bucket'}, 'object': {'key': 'test.txt'}, } } mock_event = Mock() mock_event_class.return_value = mock_event mock_processor = Mock() mock_processor_class.return_value = mock_processor mock_result = ProcessorResponse( detail=event_data['detail'], apiResponse={'success': True} ) mock_processor.process.return_value = mock_result context = Mock() result = app.handler(event_data, context) mock_event_class.assert_called_once_with(**event_data) mock_processor_class.assert_called_once_with(mock_event) mock_processor.process.assert_called_once() assert result == { 'detail': { 'bucket': {'name': 'test-bucket'}, 'object': {'key': 'test.txt'}, }, 'apiResponse': {'success': True}, } @patch('app.logger') @patch('app.FileUploadInitializeProcessor') @patch('app.FileUploadEvent') def test_handler_logs_event( self, mock_event_class, mock_processor_class, mock_logger ): """Test handler logs event information.""" event_data = { 'detail': { 'bucket': {'name': 'bucket'}, 'object': {'key': 'file.txt'}, } } mock_event = Mock() mock_event_class.return_value = mock_event mock_processor = Mock() mock_processor_class.return_value = mock_processor mock_processor.process.return_value = ProcessorResponse( detail=event_data['detail'], apiResponse={'success': True} ) app.handler(event_data, Mock()) assert mock_logger.info.called log_calls = [call.args[0] for call in mock_logger.info.call_args_list] assert any('Event:' in str(call) for call in log_calls) @patch('app.logger') @patch('app.FileUploadEvent') def test_handler_invalid_event_structure(self, mock_event_class, mock_logger): """Test handler with invalid event structure.""" mock_event_class.side_effect = ValidationError.from_exception_data( 'FileUploadEvent', [ { 'type': 'missing', 'loc': ('detail',), 'msg': 'Field required', 'input': {}, } ], ) event_data = {'invalid': 'structure'} with pytest.raises(ValidationError): app.handler(event_data, Mock()) assert mock_logger.error.called error_call = mock_logger.error.call_args[0][0] assert 'Invalid event structure' in error_call @patch('app.logger') @patch('app.FileUploadInitializeProcessor') @patch('app.FileUploadEvent') def test_handler_processor_exception( self, mock_event_class, mock_processor_class, mock_logger ): """Test handler when processor raises exception.""" mock_event = Mock() mock_event_class.return_value = mock_event mock_processor = Mock() mock_processor_class.return_value = mock_processor mock_processor.process.side_effect = Exception('Processing failed') event_data = { 'detail': { 'bucket': {'name': 'bucket'}, 'object': {'key': 'file.txt'}, } } with pytest.raises(Exception) as exc_info: app.handler(event_data, Mock()) assert 'Processing failed' in str(exc_info.value) assert mock_logger.exception.called @patch('app.logger') @patch('app.FileUploadInitializeProcessor') @patch('app.FileUploadEvent') def test_handler_logs_processing_time( self, mock_event_class, mock_processor_class, mock_logger ): """Test handler logs processing time.""" event_data = { 'detail': { 'bucket': {'name': 'bucket'}, 'object': {'key': 'file.txt'}, } } mock_event = Mock() mock_event_class.return_value = mock_event mock_processor = Mock() mock_processor_class.return_value = mock_processor mock_processor.process.return_value = ProcessorResponse( detail=event_data['detail'], apiResponse={} ) app.handler(event_data, Mock()) log_calls = [call.args[0] for call in mock_logger.info.call_args_list] assert any('Finished processing' in str(call) for call in log_calls) @patch('app.FileUploadInitializeProcessor') @patch('app.FileUploadEvent') def test_handler_returns_dict(self, mock_event_class, mock_processor_class): """Test handler returns dict format.""" event_data = { 'detail': { 'bucket': {'name': 'bucket'}, 'object': {'key': 'file.txt'}, } } mock_event = Mock() mock_event_class.return_value = mock_event mock_processor = Mock() mock_processor_class.return_value = mock_processor mock_processor.process.return_value = ProcessorResponse( detail=event_data['detail'], apiResponse={'data': 'test'} ) result = app.handler(event_data, Mock()) assert isinstance(result, dict) assert 'detail' in result assert 'apiResponse' in result class TestSentryIntegration: """Tests for Sentry integration.""" @patch('app.config.SENTRY_DSN', 'https://test@sentry.io/123') @patch('app.sentry_sdk.init') def test_sentry_initialization_with_dsn(self, mock_sentry_init): """Test Sentry is initialized when DSN is configured.""" # Note: This would need to be tested by reloading the app module # or by verifying the initialization at module import time pass @patch('app.config.SENTRY_DSN', None) def test_sentry_not_initialized_without_dsn(self): """Test Sentry is not initialized when DSN is not configured.""" # Note: This verifies config behavior when DSN is None pass