"""Unit testcases for FileUploadInitializeProcessor.""" from unittest.mock import Mock, patch import pytest from file_upload_initialize.exception import OwsServiceException from file_upload_initialize.processor import FileUploadInitializeProcessor from file_upload_initialize.schemas import FileUploadEvent, ProcessorResponse class TestFileUploadInitializeProcessorInit: """Tests for FileUploadInitializeProcessor initialization.""" def test_init_with_valid_event(self): """Test processor initialization with valid event.""" event = FileUploadEvent( detail={'bucket': {'name': 'test-bucket'}, 'object': {'key': 'test.txt'}} ) processor = FileUploadInitializeProcessor(event) assert processor._event == event class TestFileUploadInitializeProcessorProcess: """Tests for FileUploadInitializeProcessor.process method.""" @patch( 'file_upload_initialize.processor.FileUploadInitializeProcessor._update_upload_status_to_scanning' ) @patch('file_upload_initialize.processor.get_s3_connector') def test_process_updating_status_to_scanning( self, mock_get_connector, mock__update_upload_status_to_scanning, mock_file_upload, ): """Test successful updating file_upload status to scanning.""" mock_s3_connector = Mock() mock_s3_connector.get_object_metadata.return_value = { 'metadata': {'filekey': 'test-file-key-123'} } mock_get_connector.return_value = mock_s3_connector event = FileUploadEvent( detail={ 'bucket': {'name': 'test-bucket'}, 'object': {'key': 'uploads/test.csv'}, } ) mock__update_upload_status_to_scanning.return_value = mock_file_upload processor = FileUploadInitializeProcessor(event) result = processor.process() assert result.detail == event.detail assert result.apiResponse == mock_file_upload mock_s3_connector.get_object_metadata.assert_called_once_with( 'test-bucket', 'uploads/test.csv' ) mock__update_upload_status_to_scanning.assert_called_once_with( 'test-file-key-123' ) @patch('file_upload_initialize.processor.get_s3_connector') def test_process_file_key_variations(self, mock_get_connector, mock_file_upload): """Test processor handles different file-key metadata variations.""" test_cases = [ {'filekey': 'key1'}, {'file_key': 'key2'}, {'file-key': 'key3'}, ] for metadata in test_cases: mock_s3_connector = Mock() mock_s3_connector.get_object_metadata.return_value = {'metadata': metadata} mock_get_connector.return_value = mock_s3_connector event = FileUploadEvent( detail={ 'bucket': {'name': 'bucket'}, 'object': {'key': 'file.txt'}, } ) processor = FileUploadInitializeProcessor(event) with patch( 'file_upload_initialize.processor.FileUploadInitializeProcessor._update_upload_status_to_scanning' ) as mock__update_upload_status_to_scanning: mock__update_upload_status_to_scanning.return_value = mock_file_upload result = processor.process() expected_key = list(metadata.values())[0] mock__update_upload_status_to_scanning.assert_called_once_with( expected_key ) @patch('file_upload_initialize.processor.get_s3_connector') def test_process_missing_file_key_raises_error(self, mock_get_connector): """Test process raises ValueError when file-key is missing from metadata.""" mock_s3_connector = Mock() mock_s3_connector.get_object_metadata.return_value = { 'metadata': {'other_field': 'value'} } mock_get_connector.return_value = mock_s3_connector event = FileUploadEvent( detail={'bucket': {'name': 'bucket'}, 'object': {'key': 'file.txt'}} ) processor = FileUploadInitializeProcessor(event) with pytest.raises(ValueError) as exc_info: processor.process() assert 'file-key not found' in str(exc_info.value) @patch('file_upload_initialize.processor.get_s3_connector') def test_process_empty_metadata_raises_error(self, mock_get_connector): """Test process raises ValueError when metadata is empty.""" mock_s3_connector = Mock() mock_s3_connector.get_object_metadata.return_value = {'metadata': {}} mock_get_connector.return_value = mock_s3_connector event = FileUploadEvent( detail={'bucket': {'name': 'bucket'}, 'object': {'key': 'file.txt'}} ) processor = FileUploadInitializeProcessor(event) with pytest.raises(ValueError) as exc_info: processor.process() assert 'file-key not found' in str(exc_info.value) @patch('file_upload_initialize.processor.logger') @patch( 'file_upload_initialize.processor.FileUploadInitializeProcessor._update_upload_status_to_scanning' ) @patch('file_upload_initialize.processor.get_s3_connector') def test_process_logs_metadata_retrieval( self, mock_get_connector, mock__update_upload_status_to_scanning, mock_logger, mock_file_upload, ): """Test process logs metadata retrieval.""" mock_s3_connector = Mock() mock_s3_connector.get_object_metadata.return_value = { 'metadata': {'filekey': 'test-key'} } mock_get_connector.return_value = mock_s3_connector mock__update_upload_status_to_scanning.return_value = mock_file_upload event = FileUploadEvent( detail={ 'bucket': {'name': 'my-bucket'}, 'object': {'key': 'path/file.txt'}, } ) processor = FileUploadInitializeProcessor(event) processor.process() assert mock_logger.info.called log_calls = [call.args[0] for call in mock_logger.info.call_args_list] assert any('Retrieving metadata' in call for call in log_calls) assert any('s3://my-bucket/path/file.txt' in call for call in log_calls) class TestUpdatingUploadStatus: """Tests for FileUploadInitializeProcessor._update_upload_status_to_scanning method.""" @patch('file_upload_initialize.processor.ows_royalties.update_file_upload_status') def test__update_upload_status_to_scanning_success( self, mock_update_file_upload_status, mock_file_upload ): """Test successful updating status to scanning.""" mock_update_file_upload_status.return_value = mock_file_upload event = FileUploadEvent( detail={'bucket': {'name': 'bucket'}, 'object': {'key': 'file.txt'}} ) processor = FileUploadInitializeProcessor(event) result = processor._update_upload_status_to_scanning('test-file-key') assert result == mock_file_upload mock_update_file_upload_status.assert_called_once_with( 'test-file-key', {'upload_status': 'scanning'} ) @patch('file_upload_initialize.processor.logger') @patch('file_upload_initialize.processor.ows_royalties.update_file_upload_status') def test__update_upload_status_to_scanning_logs_success( self, mock_update_file_upload_status, mock_logger, mock_file_upload ): """Test updating status logs success message.""" mock_update_file_upload_status.return_value = mock_file_upload event = FileUploadEvent( detail={'bucket': {'name': 'bucket'}, 'object': {'key': 'file.txt'}} ) processor = FileUploadInitializeProcessor(event) processor._update_upload_status_to_scanning('test-file-key') assert mock_logger.info.called log_message = mock_logger.info.call_args[0][0] assert ( log_message == f'The file upload status updated to scanning: file_key=test-file-key' ) @patch('file_upload_initialize.processor.logger') @patch('file_upload_initialize.processor.ows_royalties.update_file_upload_status') def test__update_upload_status_to_scanning_api_error( self, mock_update_file_upload_status, mock_logger ): """Test updating status handles API errors.""" mock_update_file_upload_status.side_effect = OwsServiceException( 'API connection failed' ) event = FileUploadEvent( detail={'bucket': {'name': 'bucket'}, 'object': {'key': 'file.txt'}} ) processor = FileUploadInitializeProcessor(event) with pytest.raises(OwsServiceException) as exc_info: processor._update_upload_status_to_scanning('test-file-key') assert 'API connection failed' in str(exc_info.value) assert mock_logger.error.called