""" Tests for upload tasks including OneDrive and S3. """ import os import pytest from unittest.mock import Mock, patch, MagicMock from app.tasks.upload_to_onedrive import upload_to_onedrive from app.tasks.upload_to_s3 import upload_to_s3 @pytest.fixture def mock_settings(): """Mock settings for upload tests.""" with patch('app.tasks.upload_to_onedrive.settings') as onedrive_settings, \ patch('app.tasks.upload_to_s3.settings') as s3_settings: # OneDrive settings onedrive_settings.onedrive_client_id = "test_client_id" onedrive_settings.onedrive_client_secret = "test_secret" onedrive_settings.onedrive_refresh_token = "test_refresh_token" onedrive_settings.onedrive_folder_path = "test_folder" onedrive_settings.onedrive_tenant_id = "common" # S3 settings s3_settings.s3_bucket_name = "test-bucket" s3_settings.aws_access_key_id = "test_access_key" s3_settings.aws_secret_access_key = "test_secret_key" s3_settings.aws_region = "us-east-1" s3_settings.s3_folder_prefix = "documents" s3_settings.s3_storage_class = "STANDARD" s3_settings.s3_acl = None yield onedrive_settings, s3_settings @pytest.mark.unit def test_upload_to_onedrive_accepts_file_id(sample_text_file, mock_settings): """Test that upload_to_onedrive accepts file_id parameter.""" with patch('app.tasks.upload_to_onedrive.get_onedrive_token') as mock_token, \ patch('app.tasks.upload_to_onedrive.create_upload_session') as mock_session, \ patch('app.tasks.upload_to_onedrive.upload_large_file') as mock_upload, \ patch('app.tasks.upload_to_onedrive.log_task_progress'): # Setup mocks mock_token.return_value = "test_access_token" mock_session.return_value = "https://upload.url" mock_upload.return_value = {"webUrl": "https://onedrive.test/file"} # Call with file_id parameter using apply() to simulate task execution # This bypasses Celery and calls the function directly result = upload_to_onedrive.apply(args=[sample_text_file], kwargs={'file_id': 42}).get() assert result["status"] == "Completed" assert result["file_path"] == sample_text_file assert "onedrive_path" in result @pytest.mark.unit def test_upload_to_onedrive_without_file_id(sample_text_file, mock_settings): """Test that upload_to_onedrive works without file_id parameter.""" with patch('app.tasks.upload_to_onedrive.get_onedrive_token') as mock_token, \ patch('app.tasks.upload_to_onedrive.create_upload_session') as mock_session, \ patch('app.tasks.upload_to_onedrive.upload_large_file') as mock_upload, \ patch('app.tasks.upload_to_onedrive.log_task_progress'): # Setup mocks mock_token.return_value = "test_access_token" mock_session.return_value = "https://upload.url" mock_upload.return_value = {"webUrl": "https://onedrive.test/file"} # Call without file_id parameter - should use default None result = upload_to_onedrive.apply(args=[sample_text_file]).get() assert result["status"] == "Completed" assert result["file_path"] == sample_text_file @pytest.mark.unit def test_upload_to_s3_accepts_file_id(sample_text_file, mock_settings): """Test that upload_to_s3 accepts file_id parameter.""" with patch('app.tasks.upload_to_s3.boto3.client') as mock_boto_client, \ patch('app.tasks.upload_to_s3.log_task_progress'): # Setup mock S3 client mock_s3 = Mock() mock_boto_client.return_value = mock_s3 mock_s3.upload_file.return_value = None # Call with file_id parameter using apply() result = upload_to_s3.apply(args=[sample_text_file], kwargs={'file_id': 99}).get() assert result["status"] == "Completed" assert result["file"] == sample_text_file assert result["s3_bucket"] == "test-bucket" assert "s3_key" in result @pytest.mark.unit def test_upload_to_s3_without_file_id(sample_text_file, mock_settings): """Test that upload_to_s3 works without file_id parameter.""" with patch('app.tasks.upload_to_s3.boto3.client') as mock_boto_client, \ patch('app.tasks.upload_to_s3.log_task_progress'): # Setup mock S3 client mock_s3 = Mock() mock_boto_client.return_value = mock_s3 mock_s3.upload_file.return_value = None # Call without file_id parameter using apply() result = upload_to_s3.apply(args=[sample_text_file]).get() assert result["status"] == "Completed" assert result["file"] == sample_text_file @pytest.mark.unit def test_upload_to_onedrive_file_not_found(mock_settings): """Test that upload_to_onedrive raises error for missing file.""" with patch('app.tasks.upload_to_onedrive.log_task_progress'): with pytest.raises(FileNotFoundError): upload_to_onedrive.apply(args=["/nonexistent/file.pdf"], kwargs={'file_id': 1}).get() @pytest.mark.unit def test_upload_to_s3_file_not_found(mock_settings): """Test that upload_to_s3 raises error for missing file.""" with patch('app.tasks.upload_to_s3.log_task_progress'): with pytest.raises(FileNotFoundError): upload_to_s3.apply(args=["/nonexistent/file.pdf"], kwargs={'file_id': 1}).get() @pytest.mark.unit def test_upload_to_onedrive_logs_with_file_id(sample_text_file, mock_settings): """Test that upload_to_onedrive properly logs with file_id.""" with patch('app.tasks.upload_to_onedrive.get_onedrive_token') as mock_token, \ patch('app.tasks.upload_to_onedrive.create_upload_session') as mock_session, \ patch('app.tasks.upload_to_onedrive.upload_large_file') as mock_upload, \ patch('app.tasks.upload_to_onedrive.log_task_progress') as mock_log: # Setup mocks mock_token.return_value = "test_access_token" mock_session.return_value = "https://upload.url" mock_upload.return_value = {"webUrl": "https://onedrive.test/file"} # Call with file_id upload_to_onedrive.apply(args=[sample_text_file], kwargs={'file_id': 123}).get() # Verify log_task_progress was called with file_id assert mock_log.called # Check that at least one call included the file_id parameter calls_with_file_id = [call for call in mock_log.call_args_list if 'file_id' in call[1] and call[1]['file_id'] == 123] assert len(calls_with_file_id) > 0 @pytest.mark.unit def test_upload_to_s3_logs_with_file_id(sample_text_file, mock_settings): """Test that upload_to_s3 properly logs with file_id.""" with patch('app.tasks.upload_to_s3.boto3.client') as mock_boto_client, \ patch('app.tasks.upload_to_s3.log_task_progress') as mock_log: # Setup mock S3 client mock_s3 = Mock() mock_boto_client.return_value = mock_s3 mock_s3.upload_file.return_value = None # Call with file_id upload_to_s3.apply(args=[sample_text_file], kwargs={'file_id': 456}).get() # Verify log_task_progress was called with file_id assert mock_log.called # Check that at least one call included the file_id parameter calls_with_file_id = [call for call in mock_log.call_args_list if 'file_id' in call[1] and call[1]['file_id'] == 456] assert len(calls_with_file_id) > 0