"""Tests for app/tasks/send_to_all.py module.""" from unittest.mock import MagicMock, patch import pytest from app.tasks.send_to_all import ( _should_upload_to_dropbox, _should_upload_to_email, _should_upload_to_ftp, _should_upload_to_google_drive, _should_upload_to_icloud, _should_upload_to_nextcloud, _should_upload_to_onedrive, _should_upload_to_paperless, _should_upload_to_s3, _should_upload_to_sftp, _should_upload_to_webdav, get_configured_services_from_validator, send_to_all_destinations, ) @pytest.mark.unit class TestShouldUploadFunctions: """Test the _should_upload_to_* helper functions.""" @patch("app.tasks.send_to_all.settings") def test_should_upload_to_dropbox_all_configured(self, mock_settings): """Test Dropbox upload check when all credentials are configured.""" mock_settings.dropbox_app_key = "key" mock_settings.dropbox_app_secret = "secret" mock_settings.dropbox_refresh_token = "token" assert _should_upload_to_dropbox() is True @patch("app.tasks.send_to_all.settings") def test_should_upload_to_dropbox_missing_credentials(self, mock_settings): """Test Dropbox upload check when credentials are missing.""" mock_settings.dropbox_app_key = None mock_settings.dropbox_app_secret = None mock_settings.dropbox_refresh_token = None assert _should_upload_to_dropbox() is False @patch("app.tasks.send_to_all.settings") def test_should_upload_to_nextcloud_configured(self, mock_settings): """Test Nextcloud upload check.""" mock_settings.nextcloud_upload_url = "https://nextcloud.example.com" mock_settings.nextcloud_username = "user" mock_settings.nextcloud_password = "pass" assert _should_upload_to_nextcloud() is True @patch("app.tasks.send_to_all.settings") def test_should_upload_to_paperless_configured(self, mock_settings): """Test Paperless upload check.""" mock_settings.paperless_ngx_api_token = "token" mock_settings.paperless_host = "https://paperless.example.com" assert _should_upload_to_paperless() is True @patch("app.tasks.send_to_all.settings") def test_should_upload_to_google_drive_oauth(self, mock_settings): """Test Google Drive upload check with OAuth.""" mock_settings.google_drive_use_oauth = True mock_settings.google_drive_client_id = "client_id" mock_settings.google_drive_client_secret = "client_secret" mock_settings.google_drive_refresh_token = "refresh_token" mock_settings.google_drive_folder_id = "folder_id" assert _should_upload_to_google_drive() is True @patch("app.tasks.send_to_all.settings") def test_should_upload_to_google_drive_service_account(self, mock_settings): """Test Google Drive upload check with service account.""" mock_settings.google_drive_use_oauth = False mock_settings.google_drive_credentials_json = '{"type": "service_account"}' mock_settings.google_drive_folder_id = "folder_id" assert _should_upload_to_google_drive() is True @patch("app.tasks.send_to_all.settings") def test_should_upload_to_webdav_configured(self, mock_settings): """Test WebDAV upload check.""" mock_settings.webdav_url = "https://webdav.example.com" mock_settings.webdav_username = "user" mock_settings.webdav_password = "pass" assert _should_upload_to_webdav() is True @patch("app.tasks.send_to_all.settings") def test_should_upload_to_ftp_configured(self, mock_settings): """Test FTP upload check.""" mock_settings.ftp_host = "ftp.example.com" mock_settings.ftp_username = "user" mock_settings.ftp_password = "pass" assert _should_upload_to_ftp() is True @patch("app.tasks.send_to_all.settings") def test_should_upload_to_sftp_with_password(self, mock_settings): """Test SFTP upload check with password auth.""" mock_settings.sftp_host = "sftp.example.com" mock_settings.sftp_username = "user" mock_settings.sftp_password = "pass" mock_settings.sftp_private_key = None assert _should_upload_to_sftp() is True @patch("app.tasks.send_to_all.settings") def test_should_upload_to_sftp_with_key(self, mock_settings): """Test SFTP upload check with key auth.""" mock_settings.sftp_host = "sftp.example.com" mock_settings.sftp_username = "user" mock_settings.sftp_password = None mock_settings.sftp_private_key = "/path/to/key" assert _should_upload_to_sftp() is True @patch("app.tasks.send_to_all.settings") def test_should_upload_to_email_configured(self, mock_settings): """Test email upload check.""" mock_settings.dest_email_host = "smtp.example.com" mock_settings.dest_email_username = "user" mock_settings.dest_email_password = "pass" mock_settings.dest_email_default_recipient = "recipient@example.com" assert _should_upload_to_email() is True @patch("app.tasks.send_to_all.settings") def test_should_upload_to_onedrive_configured(self, mock_settings): """Test OneDrive upload check.""" mock_settings.onedrive_client_id = "client_id" mock_settings.onedrive_client_secret = "client_secret" mock_settings.onedrive_refresh_token = "refresh_token" assert _should_upload_to_onedrive() is True @patch("app.tasks.send_to_all.settings") def test_should_upload_to_s3_configured(self, mock_settings): """Test S3 upload check.""" mock_settings.s3_bucket_name = "my-bucket" mock_settings.aws_access_key_id = "key_id" mock_settings.aws_secret_access_key = "secret_key" assert _should_upload_to_s3() is True @patch("app.tasks.send_to_all.settings") def test_should_upload_to_icloud_configured(self, mock_settings): """Test iCloud upload check.""" mock_settings.icloud_username = "user@example.com" mock_settings.icloud_password = "app-specific-password" assert _should_upload_to_icloud() is True @patch("app.tasks.send_to_all.settings") def test_should_upload_to_icloud_not_configured(self, mock_settings): """Test iCloud upload check when not configured.""" mock_settings.icloud_username = None mock_settings.icloud_password = None assert _should_upload_to_icloud() is False @pytest.mark.unit class TestShouldUploadEnabledFlag: """Test that the _should_upload_to_* functions respect the explicit enabled flag.""" @patch("app.tasks.send_to_all.settings") def test_dropbox_disabled_with_credentials(self, mock_settings): """Test Dropbox upload is blocked when disabled even with valid credentials.""" mock_settings.dropbox_enabled = False mock_settings.dropbox_app_key = "key" mock_settings.dropbox_app_secret = "secret" mock_settings.dropbox_refresh_token = "token" assert _should_upload_to_dropbox() is False @patch("app.tasks.send_to_all.settings") def test_nextcloud_disabled_with_credentials(self, mock_settings): """Test Nextcloud upload is blocked when disabled even with valid credentials.""" mock_settings.nextcloud_enabled = False mock_settings.nextcloud_upload_url = "https://nextcloud.example.com" mock_settings.nextcloud_username = "user" mock_settings.nextcloud_password = "pass" assert _should_upload_to_nextcloud() is False @patch("app.tasks.send_to_all.settings") def test_paperless_disabled_with_credentials(self, mock_settings): """Test Paperless upload is blocked when disabled even with valid credentials.""" mock_settings.paperless_enabled = False mock_settings.paperless_ngx_api_token = "token" mock_settings.paperless_host = "https://paperless.example.com" assert _should_upload_to_paperless() is False @patch("app.tasks.send_to_all.settings") def test_google_drive_disabled_with_credentials(self, mock_settings): """Test Google Drive upload is blocked when disabled even with valid credentials.""" mock_settings.google_drive_enabled = False mock_settings.google_drive_use_oauth = False mock_settings.google_drive_credentials_json = '{"type": "service_account"}' mock_settings.google_drive_folder_id = "folder_id" assert _should_upload_to_google_drive() is False @patch("app.tasks.send_to_all.settings") def test_webdav_disabled_with_credentials(self, mock_settings): """Test WebDAV upload is blocked when disabled even with valid credentials.""" mock_settings.webdav_enabled = False mock_settings.webdav_url = "https://webdav.example.com" mock_settings.webdav_username = "user" mock_settings.webdav_password = "pass" assert _should_upload_to_webdav() is False @patch("app.tasks.send_to_all.settings") def test_ftp_disabled_with_credentials(self, mock_settings): """Test FTP upload is blocked when disabled even with valid credentials.""" mock_settings.ftp_enabled = False mock_settings.ftp_host = "ftp.example.com" mock_settings.ftp_username = "user" mock_settings.ftp_password = "pass" assert _should_upload_to_ftp() is False @patch("app.tasks.send_to_all.settings") def test_sftp_disabled_with_credentials(self, mock_settings): """Test SFTP upload is blocked when disabled even with valid credentials.""" mock_settings.sftp_enabled = False mock_settings.sftp_host = "sftp.example.com" mock_settings.sftp_username = "user" mock_settings.sftp_password = "pass" mock_settings.sftp_private_key = None assert _should_upload_to_sftp() is False @patch("app.tasks.send_to_all.settings") def test_email_disabled_with_credentials(self, mock_settings): """Test email upload is blocked when disabled even with valid credentials.""" mock_settings.dest_email_enabled = False mock_settings.dest_email_host = "smtp.example.com" mock_settings.dest_email_username = "user" mock_settings.dest_email_password = "pass" mock_settings.dest_email_default_recipient = "recipient@example.com" assert _should_upload_to_email() is False @patch("app.tasks.send_to_all.settings") def test_onedrive_disabled_with_credentials(self, mock_settings): """Test OneDrive upload is blocked when disabled even with valid credentials.""" mock_settings.onedrive_enabled = False mock_settings.onedrive_client_id = "client_id" mock_settings.onedrive_client_secret = "client_secret" mock_settings.onedrive_refresh_token = "refresh_token" assert _should_upload_to_onedrive() is False @patch("app.tasks.send_to_all.settings") def test_s3_disabled_with_credentials(self, mock_settings): """Test S3 upload is blocked when disabled even with valid credentials.""" mock_settings.s3_enabled = False mock_settings.s3_bucket_name = "my-bucket" mock_settings.aws_access_key_id = "key_id" mock_settings.aws_secret_access_key = "secret_key" assert _should_upload_to_s3() is False @patch("app.tasks.send_to_all.settings") def test_icloud_disabled_with_credentials(self, mock_settings): """Test iCloud upload is blocked when disabled even with valid credentials.""" mock_settings.icloud_enabled = False mock_settings.icloud_username = "user@example.com" mock_settings.icloud_password = "app-specific-password" assert _should_upload_to_icloud() is False @pytest.mark.unit class TestGetConfiguredServicesFromValidator: """Test get_configured_services_from_validator function.""" @patch("app.tasks.send_to_all.get_provider_status") def test_returns_configured_services(self, mock_get_status): """Test that configured services are returned correctly.""" mock_get_status.return_value = { "Dropbox": {"configured": True, "enabled": True}, "NextCloud": {"configured": False, "enabled": True}, "S3 Storage": {"configured": True, "enabled": True}, } result = get_configured_services_from_validator() assert result["dropbox"] is True assert result["nextcloud"] is False assert result["s3"] is True @patch("app.tasks.send_to_all.get_provider_status") def test_handles_missing_providers(self, mock_get_status): """Test handling when some providers are not in status.""" mock_get_status.return_value = { "Dropbox": {"configured": True, "enabled": True}, } result = get_configured_services_from_validator() assert result["dropbox"] is True # Other services not in result @patch("app.tasks.send_to_all.get_provider_status") def test_configured_but_disabled_service_not_active(self, mock_get_status): """Test that a configured but disabled service is not returned as active.""" mock_get_status.return_value = { "Dropbox": {"configured": True, "enabled": False}, "S3 Storage": {"configured": True, "enabled": True}, } result = get_configured_services_from_validator() assert result["dropbox"] is False assert result["s3"] is True @patch("app.tasks.send_to_all.get_provider_status") def test_missing_enabled_field_defaults_to_true_for_backward_compatibility(self, mock_get_status): """Test that missing 'enabled' key defaults to True (backward compatible).""" mock_get_status.return_value = { "Dropbox": {"configured": True}, } result = get_configured_services_from_validator() assert result["dropbox"] is True @pytest.mark.unit class TestSendToAllDestinations: """Test send_to_all_destinations task.""" @patch("app.tasks.send_to_all.log_task_progress") def test_file_not_found_error(self, mock_log): """Test that FileNotFoundError is raised when file doesn't exist.""" result = send_to_all_destinations.apply(args=["/nonexistent/file.pdf"]) # When task raises an exception, result.failed() returns True assert result.failed() # The exception should be FileNotFoundError assert isinstance(result.result, FileNotFoundError) @patch("app.tasks.send_to_all.SessionLocal") @patch("app.tasks.send_to_all.log_task_progress") @patch("app.tasks.send_to_all.settings") @patch("app.tasks.send_to_all._should_upload_to_dropbox") @patch("app.tasks.send_to_all._should_upload_to_nextcloud") @patch("app.tasks.send_to_all._should_upload_to_paperless") @patch("app.tasks.send_to_all._should_upload_to_google_drive") @patch("app.tasks.send_to_all._should_upload_to_webdav") @patch("app.tasks.send_to_all._should_upload_to_ftp") @patch("app.tasks.send_to_all._should_upload_to_sftp") @patch("app.tasks.send_to_all._should_upload_to_email") @patch("app.tasks.send_to_all._should_upload_to_onedrive") @patch("app.tasks.send_to_all._should_upload_to_sharepoint") @patch("app.tasks.send_to_all._should_upload_to_icloud") @patch("app.tasks.send_to_all._should_upload_to_s3") @patch("app.tasks.send_to_all.upload_to_dropbox") def test_queues_single_configured_service( self, mock_upload, mock_s3, mock_icloud, mock_sharepoint, mock_onedrive, mock_email, mock_sftp, mock_ftp, mock_webdav, mock_google, mock_paperless, mock_nextcloud, mock_should, mock_settings, mock_log, mock_session_local, tmp_path, ): """Test queueing upload to a single configured service.""" test_file = tmp_path / "test.pdf" test_file.write_text("test") mock_should.return_value = True # Mock all other services to return False mock_nextcloud.return_value = False mock_paperless.return_value = False mock_google.return_value = False mock_webdav.return_value = False mock_ftp.return_value = False mock_sftp.return_value = False mock_email.return_value = False mock_onedrive.return_value = False mock_s3.return_value = False mock_sharepoint.return_value = False mock_icloud.return_value = False mock_upload.delay.return_value = MagicMock(id="task-123") result = send_to_all_destinations.apply(args=[str(test_file), False, 1]) assert result.result["status"] == "Queued" mock_upload.delay.assert_called_once() @patch("app.tasks.send_to_all.SessionLocal") @patch("app.tasks.send_to_all.log_task_progress") @patch("app.tasks.send_to_all.settings") @patch("app.tasks.send_to_all._should_upload_to_dropbox") @patch("app.tasks.send_to_all._should_upload_to_icloud") @patch("app.tasks.send_to_all._should_upload_to_sharepoint") @patch("app.tasks.send_to_all._should_upload_to_s3") @patch("app.tasks.send_to_all._should_upload_to_nextcloud") @patch("app.tasks.send_to_all._should_upload_to_paperless") @patch("app.tasks.send_to_all._should_upload_to_google_drive") @patch("app.tasks.send_to_all._should_upload_to_webdav") @patch("app.tasks.send_to_all._should_upload_to_ftp") @patch("app.tasks.send_to_all._should_upload_to_sftp") @patch("app.tasks.send_to_all._should_upload_to_email") @patch("app.tasks.send_to_all._should_upload_to_onedrive") @patch("app.tasks.send_to_all.upload_to_dropbox") @patch("app.tasks.send_to_all.upload_to_s3") def test_queues_multiple_services( self, mock_s3_upload, mock_dropbox_upload, mock_onedrive, mock_email, mock_sftp, mock_ftp, mock_webdav, mock_google, mock_paperless, mock_nextcloud, mock_should_s3, mock_sharepoint, mock_icloud, mock_should_dropbox, mock_settings, mock_log, mock_session_local, tmp_path, ): """Test queueing uploads to multiple services.""" test_file = tmp_path / "test.pdf" test_file.write_text("test") mock_should_dropbox.return_value = True mock_should_s3.return_value = True # Mock all other services to return False mock_nextcloud.return_value = False mock_paperless.return_value = False mock_google.return_value = False mock_webdav.return_value = False mock_ftp.return_value = False mock_sftp.return_value = False mock_email.return_value = False mock_onedrive.return_value = False mock_sharepoint.return_value = False mock_icloud.return_value = False mock_dropbox_upload.delay.return_value = MagicMock(id="dropbox-task") mock_s3_upload.delay.return_value = MagicMock(id="s3-task") result = send_to_all_destinations.apply(args=[str(test_file), False, 1]) assert result.result["status"] == "Queued" mock_dropbox_upload.delay.assert_called_once() mock_s3_upload.delay.assert_called_once() @patch("app.tasks.send_to_all.SessionLocal") @patch("app.tasks.send_to_all.log_task_progress") @patch("app.tasks.send_to_all.settings") @patch("app.tasks.send_to_all._should_upload_to_dropbox") @patch("app.tasks.send_to_all._should_upload_to_nextcloud") @patch("app.tasks.send_to_all._should_upload_to_paperless") @patch("app.tasks.send_to_all._should_upload_to_google_drive") @patch("app.tasks.send_to_all._should_upload_to_webdav") @patch("app.tasks.send_to_all._should_upload_to_ftp") @patch("app.tasks.send_to_all._should_upload_to_sftp") @patch("app.tasks.send_to_all._should_upload_to_email") @patch("app.tasks.send_to_all._should_upload_to_onedrive") @patch("app.tasks.send_to_all._should_upload_to_sharepoint") @patch("app.tasks.send_to_all._should_upload_to_icloud") @patch("app.tasks.send_to_all._should_upload_to_s3") def test_skips_unconfigured_services( self, mock_s3, mock_icloud, mock_sharepoint, mock_onedrive, mock_email, mock_sftp, mock_ftp, mock_webdav, mock_google, mock_paperless, mock_nextcloud, mock_should, mock_settings, mock_log, mock_session_local, tmp_path, ): """Test that unconfigured services are skipped.""" test_file = tmp_path / "test.pdf" test_file.write_text("test") # Set all _should_upload_* functions to return False mock_should.return_value = False mock_nextcloud.return_value = False mock_paperless.return_value = False mock_google.return_value = False mock_webdav.return_value = False mock_ftp.return_value = False mock_sftp.return_value = False mock_email.return_value = False mock_onedrive.return_value = False mock_s3.return_value = False mock_sharepoint.return_value = False mock_icloud.return_value = False result = send_to_all_destinations.apply(args=[str(test_file), False, 1]) # No uploads should be queued assert result.result["status"] == "Queued" # Check that message indicates 0 uploads assert "0 upload" in result.result["tasks"] or len(result.result["tasks"]) == 0 @patch("app.tasks.send_to_all.log_task_progress") @patch("app.tasks.send_to_all.SessionLocal") @patch("app.tasks.send_to_all.settings") @patch("app.tasks.send_to_all._should_upload_to_dropbox") @patch("app.tasks.send_to_all._should_upload_to_nextcloud") @patch("app.tasks.send_to_all._should_upload_to_paperless") @patch("app.tasks.send_to_all._should_upload_to_google_drive") @patch("app.tasks.send_to_all._should_upload_to_webdav") @patch("app.tasks.send_to_all._should_upload_to_ftp") @patch("app.tasks.send_to_all._should_upload_to_sftp") @patch("app.tasks.send_to_all._should_upload_to_email") @patch("app.tasks.send_to_all._should_upload_to_onedrive") @patch("app.tasks.send_to_all._should_upload_to_sharepoint") @patch("app.tasks.send_to_all._should_upload_to_icloud") @patch("app.tasks.send_to_all._should_upload_to_s3") @patch("app.tasks.send_to_all.upload_to_dropbox") def test_with_file_id_parameter( self, mock_upload, mock_s3, mock_icloud, mock_sharepoint, mock_onedrive, mock_email, mock_sftp, mock_ftp, mock_webdav, mock_google, mock_paperless, mock_nextcloud, mock_should, mock_settings, mock_session_local, mock_log, tmp_path, ): """Test send_to_all with explicit file_id parameter.""" test_file = tmp_path / "test.pdf" test_file.write_text("test") mock_should.return_value = True # Mock all other services to return False mock_nextcloud.return_value = False mock_paperless.return_value = False mock_google.return_value = False mock_webdav.return_value = False mock_ftp.return_value = False mock_sftp.return_value = False mock_email.return_value = False mock_onedrive.return_value = False mock_s3.return_value = False mock_sharepoint.return_value = False mock_icloud.return_value = False mock_upload.delay.return_value = MagicMock(id="task-123") result = send_to_all_destinations.apply(args=[str(test_file), False, 42]) mock_upload.delay.assert_called_once() # Verify file_id was passed to the upload task call_kwargs = mock_upload.delay.call_args[1] assert call_kwargs.get("file_id") == 42 @patch("app.tasks.send_to_all.SessionLocal") @patch("app.tasks.send_to_all.log_task_progress") @patch("app.tasks.send_to_all.settings") @patch("app.tasks.send_to_all._should_upload_to_dropbox") @patch("app.tasks.send_to_all._should_upload_to_nextcloud") @patch("app.tasks.send_to_all._should_upload_to_paperless") @patch("app.tasks.send_to_all._should_upload_to_google_drive") @patch("app.tasks.send_to_all._should_upload_to_webdav") @patch("app.tasks.send_to_all._should_upload_to_ftp") @patch("app.tasks.send_to_all._should_upload_to_sftp") @patch("app.tasks.send_to_all._should_upload_to_email") @patch("app.tasks.send_to_all._should_upload_to_onedrive") @patch("app.tasks.send_to_all._should_upload_to_sharepoint") @patch("app.tasks.send_to_all._should_upload_to_icloud") @patch("app.tasks.send_to_all._should_upload_to_s3") @patch("app.tasks.send_to_all.get_configured_services_from_validator") @patch("app.tasks.send_to_all.upload_to_dropbox") def test_uses_validator_when_enabled( self, mock_upload, mock_validator, mock_s3, mock_icloud, mock_sharepoint, mock_onedrive, mock_email, mock_sftp, mock_ftp, mock_webdav, mock_google, mock_paperless, mock_nextcloud, mock_should_dropbox, mock_settings, mock_log, mock_session_local, tmp_path, ): """Test that validator is used when use_validator=True.""" test_file = tmp_path / "test.pdf" test_file.write_text("test") mock_validator.return_value = {"dropbox": True} # Mock all should_upload functions to return False (they won't be called when validator is used, but just in case) mock_should_dropbox.return_value = False mock_nextcloud.return_value = False mock_paperless.return_value = False mock_google.return_value = False mock_webdav.return_value = False mock_ftp.return_value = False mock_sftp.return_value = False mock_email.return_value = False mock_onedrive.return_value = False mock_s3.return_value = False mock_sharepoint.return_value = False mock_icloud.return_value = False mock_upload.delay.return_value = MagicMock(id="task-123") result = send_to_all_destinations.apply(args=[str(test_file), True, 1]) mock_validator.assert_called_once() mock_upload.delay.assert_called_once() @patch("app.tasks.send_to_all.SessionLocal") @patch("app.tasks.send_to_all.log_task_progress") @patch("app.tasks.send_to_all.settings") @patch("app.tasks.send_to_all._should_upload_to_dropbox") @patch("app.tasks.send_to_all._should_upload_to_nextcloud") @patch("app.tasks.send_to_all._should_upload_to_paperless") @patch("app.tasks.send_to_all._should_upload_to_google_drive") @patch("app.tasks.send_to_all._should_upload_to_webdav") @patch("app.tasks.send_to_all._should_upload_to_ftp") @patch("app.tasks.send_to_all._should_upload_to_sftp") @patch("app.tasks.send_to_all._should_upload_to_email") @patch("app.tasks.send_to_all._should_upload_to_onedrive") @patch("app.tasks.send_to_all._should_upload_to_sharepoint") @patch("app.tasks.send_to_all._should_upload_to_icloud") @patch("app.tasks.send_to_all._should_upload_to_s3") @patch("app.tasks.send_to_all.get_configured_services_from_validator") def test_validator_exception_fallback( self, mock_validator, mock_s3, mock_icloud, mock_sharepoint, mock_onedrive, mock_email, mock_sftp, mock_ftp, mock_webdav, mock_google, mock_paperless, mock_nextcloud, mock_should_dropbox, mock_settings, mock_log, mock_session_local, tmp_path, ): """Test fallback to individual checks when validator fails.""" test_file = tmp_path / "test.pdf" test_file.write_text("test") mock_validator.side_effect = Exception("Validator error") # Set all _should_upload_* functions to return False mock_should_dropbox.return_value = False mock_nextcloud.return_value = False mock_paperless.return_value = False mock_google.return_value = False mock_webdav.return_value = False mock_ftp.return_value = False mock_sftp.return_value = False mock_email.return_value = False mock_onedrive.return_value = False mock_s3.return_value = False mock_sharepoint.return_value = False mock_icloud.return_value = False # Should not raise, should fall back to individual checks result = send_to_all_destinations.apply(args=[str(test_file), True, 1]) assert result.result["status"] == "Queued" @patch("app.tasks.send_to_all.SessionLocal") @patch("app.tasks.send_to_all.log_task_progress") @patch("app.tasks.send_to_all.settings") @patch("app.tasks.send_to_all._should_upload_to_dropbox") @patch("app.tasks.send_to_all._should_upload_to_nextcloud") @patch("app.tasks.send_to_all._should_upload_to_paperless") @patch("app.tasks.send_to_all._should_upload_to_google_drive") @patch("app.tasks.send_to_all._should_upload_to_webdav") @patch("app.tasks.send_to_all._should_upload_to_ftp") @patch("app.tasks.send_to_all._should_upload_to_sftp") @patch("app.tasks.send_to_all._should_upload_to_email") @patch("app.tasks.send_to_all._should_upload_to_onedrive") @patch("app.tasks.send_to_all._should_upload_to_sharepoint") @patch("app.tasks.send_to_all._should_upload_to_icloud") @patch("app.tasks.send_to_all._should_upload_to_s3") @patch("app.tasks.send_to_all.upload_to_dropbox") def test_handles_upload_task_queue_error( self, mock_upload, mock_s3, mock_icloud, mock_sharepoint, mock_onedrive, mock_email, mock_sftp, mock_ftp, mock_webdav, mock_google, mock_paperless, mock_nextcloud, mock_should, mock_settings, mock_log, mock_session_local, tmp_path, ): """Test handling when queueing upload task fails.""" test_file = tmp_path / "test.pdf" test_file.write_text("test") mock_should.return_value = True # Mock all other services to return False mock_nextcloud.return_value = False mock_paperless.return_value = False mock_google.return_value = False mock_webdav.return_value = False mock_ftp.return_value = False mock_sftp.return_value = False mock_email.return_value = False mock_onedrive.return_value = False mock_s3.return_value = False mock_sharepoint.return_value = False mock_icloud.return_value = False mock_upload.delay.side_effect = Exception("Queue error") # Should not raise, should log error result = send_to_all_destinations.apply(args=[str(test_file), False, 1]) assert result.result["status"] == "Queued" # Error should be recorded in results assert "dropbox_error" in result.result["tasks"] @patch("app.tasks.send_to_all._should_upload_to_icloud") @patch("app.tasks.send_to_all._should_upload_to_sharepoint") @patch("app.tasks.send_to_all._should_upload_to_s3") @patch("app.tasks.send_to_all._should_upload_to_onedrive") @patch("app.tasks.send_to_all._should_upload_to_email") @patch("app.tasks.send_to_all._should_upload_to_sftp") @patch("app.tasks.send_to_all._should_upload_to_ftp") @patch("app.tasks.send_to_all._should_upload_to_webdav") @patch("app.tasks.send_to_all._should_upload_to_google_drive") @patch("app.tasks.send_to_all._should_upload_to_paperless") @patch("app.tasks.send_to_all._should_upload_to_nextcloud") @patch("app.tasks.send_to_all._should_upload_to_dropbox") @patch("app.tasks.send_to_all.log_task_progress") @patch("app.tasks.send_to_all.SessionLocal") @patch("app.tasks.send_to_all.settings") def test_fallback_file_id_lookup( self, mock_settings, mock_session_local, mock_log, mock_dropbox, mock_nextcloud, mock_paperless, mock_google, mock_webdav, mock_ftp, mock_sftp, mock_email, mock_onedrive, mock_s3, mock_sharepoint, mock_icloud, tmp_path, ): """Test file_id lookup fallback when not provided.""" from app.models import FileRecord test_file = tmp_path / "test.pdf" test_file.write_text("test") mock_settings.workdir = str(tmp_path) # Disable all upload services — this test only checks the DB lookup fallback mock_dropbox.return_value = False mock_nextcloud.return_value = False mock_paperless.return_value = False mock_google.return_value = False mock_webdav.return_value = False mock_ftp.return_value = False mock_sftp.return_value = False mock_email.return_value = False mock_onedrive.return_value = False mock_s3.return_value = False mock_sharepoint.return_value = False mock_icloud.return_value = False # Mock database session mock_db = MagicMock() mock_query = MagicMock() mock_file_record = MagicMock(spec=FileRecord) mock_file_record.id = 123 mock_query.first.return_value = mock_file_record mock_db.query.return_value.filter.return_value = mock_query mock_session_local.return_value.__enter__.return_value = mock_db result = send_to_all_destinations.apply(args=[str(test_file), False, None]) # Should attempt database lookup mock_db.query.assert_called() @patch("app.tasks.send_to_all.SessionLocal") @patch("app.tasks.send_to_all.log_task_progress") @patch("app.tasks.send_to_all.settings") @patch("app.tasks.send_to_all._should_upload_to_dropbox") @patch("app.tasks.send_to_all._should_upload_to_nextcloud") @patch("app.tasks.send_to_all._should_upload_to_paperless") @patch("app.tasks.send_to_all._should_upload_to_google_drive") @patch("app.tasks.send_to_all._should_upload_to_webdav") @patch("app.tasks.send_to_all._should_upload_to_ftp") @patch("app.tasks.send_to_all._should_upload_to_sftp") @patch("app.tasks.send_to_all._should_upload_to_email") @patch("app.tasks.send_to_all._should_upload_to_onedrive") @patch("app.tasks.send_to_all._should_upload_to_sharepoint") @patch("app.tasks.send_to_all._should_upload_to_icloud") @patch("app.tasks.send_to_all._should_upload_to_s3") def test_should_upload_check_exception_handling( self, mock_s3, mock_icloud, mock_sharepoint, mock_onedrive, mock_email, mock_sftp, mock_ftp, mock_webdav, mock_google, mock_paperless, mock_nextcloud, mock_should, mock_settings, mock_log, mock_session_local, tmp_path, ): """Test that exceptions in should_upload checks are handled.""" test_file = tmp_path / "test.pdf" test_file.write_text("test") mock_should.side_effect = Exception("Configuration check error") # Mock all other services to return False mock_nextcloud.return_value = False mock_paperless.return_value = False mock_google.return_value = False mock_webdav.return_value = False mock_ftp.return_value = False mock_sftp.return_value = False mock_email.return_value = False mock_onedrive.return_value = False mock_s3.return_value = False mock_sharepoint.return_value = False mock_icloud.return_value = False # Should not raise, should treat as not configured result = send_to_all_destinations.apply(args=[str(test_file), False, 1]) assert result.result["status"] == "Queued"