diff --git a/tests/test_api_openai.py b/tests/test_api_openai.py index ea34389e..0e050900 100644 --- a/tests/test_api_openai.py +++ b/tests/test_api_openai.py @@ -129,7 +129,7 @@ class TestOpenAIConnectionErrors: def test_openai_unexpected_exception(self, mock_settings, mock_openai_class, client): """Test handling of unexpected exceptions.""" mock_settings.openai_api_key = "sk-test-key" - + # Raise an unexpected exception during OpenAI client creation mock_openai_class.side_effect = RuntimeError("Unexpected error") diff --git a/tests/test_auth.py b/tests/test_auth.py index 89f46110..0fdf5686 100644 --- a/tests/test_auth.py +++ b/tests/test_auth.py @@ -361,9 +361,7 @@ class TestOAuthLogin: result = await oauth_login(mock_request) assert result == "oauth_redirect" - mock_authentik.authorize_redirect.assert_called_once_with( - mock_request, "http://localhost/oauth-callback" - ) + mock_authentik.authorize_redirect.assert_called_once_with(mock_request, "http://localhost/oauth-callback") @pytest.mark.unit diff --git a/tests/test_diagnostic.py b/tests/test_diagnostic.py index 0b1b166b..403f8c06 100644 --- a/tests/test_diagnostic.py +++ b/tests/test_diagnostic.py @@ -1,6 +1,6 @@ """Tests for app/api/diagnostic.py module.""" -from unittest.mock import MagicMock, patch +from unittest.mock import patch import pytest diff --git a/tests/test_file_splitting.py b/tests/test_file_splitting.py index 54fc822e..4c488821 100644 --- a/tests/test_file_splitting.py +++ b/tests/test_file_splitting.py @@ -517,9 +517,10 @@ class TestSplitPdfBySizeEdgeCases: def test_returns_empty_list_for_zero_page_pdf(self, tmp_path): """Test handling of PDF with zero pages.""" - from app.utils.file_splitting import split_pdf_by_size from pypdf import PdfWriter + from app.utils.file_splitting import split_pdf_by_size + # Create a technically valid but empty PDF empty_pdf = tmp_path / "empty.pdf" writer = PdfWriter() diff --git a/tests/test_filename_utils.py b/tests/test_filename_utils.py index 20f07249..46b95e67 100644 --- a/tests/test_filename_utils.py +++ b/tests/test_filename_utils.py @@ -425,6 +425,8 @@ class TestSanitizeFilenameEdgeCases: def test_handles_empty_string(self): """Test with empty string.""" + from app.utils.filename_utils import sanitize_filename + result = sanitize_filename("") # Should return a default document name assert "document_" in result @@ -432,23 +434,31 @@ class TestSanitizeFilenameEdgeCases: def test_handles_only_periods(self): """Test with only periods.""" + from app.utils.filename_utils import sanitize_filename + result = sanitize_filename("...") # Should return a default document name assert "document_" in result def test_handles_only_dots(self): """Test with single dot.""" + from app.utils.filename_utils import sanitize_filename + result = sanitize_filename(".") # Should return a default document name assert "document_" in result def test_preserves_multiple_extensions(self): """Test that multiple extensions are preserved.""" + from app.utils.filename_utils import sanitize_filename + result = sanitize_filename("file.tar.gz") assert ".tar.gz" in result or "file_tar_gz" in result def test_removes_null_bytes(self): """Test that null bytes are removed.""" + from app.utils.filename_utils import sanitize_filename + result = sanitize_filename("file\x00name.pdf") assert "\x00" not in result assert "file" in result @@ -456,6 +466,8 @@ class TestSanitizeFilenameEdgeCases: def test_handles_unicode_characters(self): """Test handling of unicode characters.""" + from app.utils.filename_utils import sanitize_filename + result = sanitize_filename("文档.pdf") # Should preserve unicode or convert safely assert ".pdf" in result @@ -468,31 +480,39 @@ class TestExtractRemotePathEdgeCases: def test_file_not_in_base_dir(self): """Test when file is not a subdirectory of base_dir.""" + from app.utils.filename_utils import extract_remote_path + result = extract_remote_path("/other/path/file.pdf", "/base/dir", "/remote") # Should just use filename assert result == "remote/file.pdf" def test_multiple_processed_directories(self): """Test path with multiple 'processed' directories.""" - result = extract_remote_path( - "/base/processed/subdir/processed/file.pdf", "/base", "/remote" - ) + from app.utils.filename_utils import extract_remote_path + + result = extract_remote_path("/base/processed/subdir/processed/file.pdf", "/base", "/remote") # Should remove all 'processed' directories assert "processed" not in result.lower() def test_remote_base_with_trailing_slash(self): """Test remote base that already has trailing slash.""" + from app.utils.filename_utils import extract_remote_path + result = extract_remote_path("/base/file.pdf", "/base", "/remote/") # Should handle gracefully assert result.startswith("remote/") def test_empty_remote_base(self): """Test with empty remote base.""" + from app.utils.filename_utils import extract_remote_path + result = extract_remote_path("/base/subdir/file.pdf", "/base", "") assert result == "subdir/file.pdf" def test_windows_style_separators(self, monkeypatch): """Test handling of Windows-style path separators.""" + from app.utils.filename_utils import extract_remote_path + result = extract_remote_path("/base/subdir/file.pdf", "/base", "/remote") # Should use forward slashes in output assert "\\" not in result diff --git a/tests/test_send_to_all.py b/tests/test_send_to_all.py index a2a57bc4..f87e8fc0 100644 --- a/tests/test_send_to_all.py +++ b/tests/test_send_to_all.py @@ -1,6 +1,5 @@ """Tests for app/tasks/send_to_all.py module.""" -import os from unittest.mock import MagicMock, patch import pytest @@ -247,9 +246,7 @@ class TestSendToAllDestinations: @patch("app.tasks.send_to_all.settings") @patch("app.tasks.send_to_all._should_upload_to_dropbox") @patch("app.tasks.send_to_all.upload_to_dropbox") - def test_with_file_id_parameter( - self, mock_upload, mock_should, mock_settings, mock_session_local, tmp_path - ): + def test_with_file_id_parameter(self, mock_upload, mock_should, mock_settings, mock_session_local, tmp_path): """Test send_to_all with explicit file_id parameter.""" test_file = tmp_path / "test.pdf" test_file.write_text("test") @@ -267,9 +264,7 @@ class TestSendToAllDestinations: @patch("app.tasks.send_to_all.settings") @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_settings, tmp_path - ): + def test_uses_validator_when_enabled(self, mock_upload, mock_validator, mock_settings, tmp_path): """Test that validator is used when use_validator=True.""" test_file = tmp_path / "test.pdf" test_file.write_text("test") @@ -299,9 +294,7 @@ class TestSendToAllDestinations: @patch("app.tasks.send_to_all.settings") @patch("app.tasks.send_to_all._should_upload_to_dropbox") @patch("app.tasks.send_to_all.upload_to_dropbox") - def test_handles_upload_task_queue_error( - self, mock_upload, mock_should, mock_settings, tmp_path - ): + def test_handles_upload_task_queue_error(self, mock_upload, mock_should, mock_settings, tmp_path): """Test handling when queueing upload task fails.""" test_file = tmp_path / "test.pdf" test_file.write_text("test") diff --git a/tests/test_settings_service_coverage.py b/tests/test_settings_service_coverage.py index be70dde4..f8be2de4 100644 --- a/tests/test_settings_service_coverage.py +++ b/tests/test_settings_service_coverage.py @@ -8,7 +8,7 @@ Focuses on: - Mixed encryption states """ -from unittest.mock import patch +from unittest.mock import MagicMock, patch import pytest from sqlalchemy.exc import SQLAlchemyError @@ -397,7 +397,7 @@ class TestSaveSettingErrors: mock_db.commit.side_effect = SQLAlchemyError("Database error") success, error = save_setting(mock_db, "test_key", "test_value") - + assert success is False assert "error" in error.lower() or "failed" in error.lower() # Should rollback on error diff --git a/tests/test_upload_to_s3.py b/tests/test_upload_to_s3.py index c20c0c46..e5ba8762 100644 --- a/tests/test_upload_to_s3.py +++ b/tests/test_upload_to_s3.py @@ -1,6 +1,5 @@ """Tests for app/tasks/upload_to_s3.py module.""" -import os from unittest.mock import MagicMock, patch import pytest @@ -20,7 +19,7 @@ class TestUploadToS3: # Setup test_file = tmp_path / "test.pdf" test_file.write_text("test content") - + mock_settings.s3_bucket_name = "my-bucket" mock_settings.aws_access_key_id = "AKIAIOSFODNN7EXAMPLE" mock_settings.aws_secret_access_key = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" @@ -39,7 +38,7 @@ class TestUploadToS3: assert result.result["status"] == "Completed" assert result.result["s3_bucket"] == "my-bucket" assert result.result["s3_key"] == "documents/test.pdf" - + mock_s3.upload_file.assert_called_once() call_args = mock_s3.upload_file.call_args assert call_args[0][0] == str(test_file) @@ -54,7 +53,7 @@ class TestUploadToS3: """Test S3 upload without folder prefix.""" test_file = tmp_path / "test.pdf" test_file.write_text("test content") - + mock_settings.s3_bucket_name = "my-bucket" mock_settings.aws_access_key_id = "key" mock_settings.aws_secret_access_key = "secret" @@ -79,7 +78,7 @@ class TestUploadToS3: """Test that folder prefix gets trailing slash added.""" test_file = tmp_path / "test.pdf" test_file.write_text("test content") - + mock_settings.s3_bucket_name = "my-bucket" mock_settings.aws_access_key_id = "key" mock_settings.aws_secret_access_key = "secret" @@ -102,7 +101,7 @@ class TestUploadToS3: mock_settings.s3_bucket_name = "my-bucket" mock_settings.aws_access_key_id = "key" mock_settings.aws_secret_access_key = "secret" - + with pytest.raises(FileNotFoundError): upload_to_s3.apply(args=["/nonexistent/file.pdf"]) @@ -111,7 +110,7 @@ class TestUploadToS3: """Test S3 upload with missing bucket name.""" test_file = tmp_path / "test.pdf" test_file.write_text("test content") - + mock_settings.s3_bucket_name = None mock_settings.aws_access_key_id = "key" mock_settings.aws_secret_access_key = "secret" @@ -124,7 +123,7 @@ class TestUploadToS3: """Test S3 upload with missing AWS credentials.""" test_file = tmp_path / "test.pdf" test_file.write_text("test content") - + mock_settings.s3_bucket_name = "my-bucket" mock_settings.aws_access_key_id = None mock_settings.aws_secret_access_key = None @@ -138,7 +137,7 @@ class TestUploadToS3: """Test S3 upload with boto3 ClientError.""" test_file = tmp_path / "test.pdf" test_file.write_text("test content") - + mock_settings.s3_bucket_name = "my-bucket" mock_settings.aws_access_key_id = "key" mock_settings.aws_secret_access_key = "secret" @@ -161,7 +160,7 @@ class TestUploadToS3: """Test S3 upload with generic exception.""" test_file = tmp_path / "test.pdf" test_file.write_text("test content") - + mock_settings.s3_bucket_name = "my-bucket" mock_settings.aws_access_key_id = "key" mock_settings.aws_secret_access_key = "secret" @@ -183,7 +182,7 @@ class TestUploadToS3: """Test S3 upload with different storage classes.""" test_file = tmp_path / "test.pdf" test_file.write_text("test content") - + mock_settings.s3_bucket_name = "my-bucket" mock_settings.aws_access_key_id = "key" mock_settings.aws_secret_access_key = "secret" @@ -206,7 +205,7 @@ class TestUploadToS3: """Test that the S3 URL is properly generated.""" test_file = tmp_path / "test.pdf" test_file.write_text("test content") - + mock_settings.s3_bucket_name = "my-bucket" mock_settings.aws_access_key_id = "key" mock_settings.aws_secret_access_key = "secret" diff --git a/tests/test_upload_to_sftp.py b/tests/test_upload_to_sftp.py index 46533a76..a890b159 100644 --- a/tests/test_upload_to_sftp.py +++ b/tests/test_upload_to_sftp.py @@ -1,7 +1,6 @@ """Tests for app/tasks/upload_to_sftp.py module.""" -import os -from unittest.mock import MagicMock, Mock, patch +from unittest.mock import MagicMock, patch import paramiko import pytest @@ -20,7 +19,7 @@ class TestUploadToSFTP: # Setup test_file = tmp_path / "test.pdf" test_file.write_text("test content") - + mock_settings.sftp_host = "sftp.example.com" mock_settings.sftp_port = 22 mock_settings.sftp_username = "testuser" @@ -60,7 +59,7 @@ class TestUploadToSFTP: # Setup test_file = tmp_path / "test.pdf" test_file.write_text("test content") - + mock_settings.sftp_host = "sftp.example.com" mock_settings.sftp_port = 22 mock_settings.sftp_username = "testuser" @@ -92,7 +91,7 @@ class TestUploadToSFTP: """Test SFTP upload with host key verification disabled.""" test_file = tmp_path / "test.pdf" test_file.write_text("test content") - + mock_settings.sftp_host = "sftp.example.com" mock_settings.sftp_port = 22 mock_settings.sftp_username = "testuser" @@ -122,7 +121,7 @@ class TestUploadToSFTP: mock_settings.sftp_host = "sftp.example.com" mock_settings.sftp_port = 22 mock_settings.sftp_username = "testuser" - + with pytest.raises(FileNotFoundError): upload_to_sftp.apply(args=["/nonexistent/file.pdf"]) @@ -131,7 +130,7 @@ class TestUploadToSFTP: """Test SFTP upload with missing configuration.""" test_file = tmp_path / "test.pdf" test_file.write_text("test content") - + mock_settings.sftp_host = None mock_settings.sftp_port = None mock_settings.sftp_username = None @@ -147,7 +146,7 @@ class TestUploadToSFTP: """Test SFTP upload with no authentication method available.""" test_file = tmp_path / "test.pdf" test_file.write_text("test content") - + mock_settings.sftp_host = "sftp.example.com" mock_settings.sftp_port = 22 mock_settings.sftp_username = "testuser" @@ -169,7 +168,7 @@ class TestUploadToSFTP: """Test that remote directories are created as needed.""" test_file = tmp_path / "test.pdf" test_file.write_text("test content") - + mock_settings.sftp_host = "sftp.example.com" mock_settings.sftp_port = 22 mock_settings.sftp_username = "testuser" @@ -181,7 +180,7 @@ class TestUploadToSFTP: mock_ssh = MagicMock() mock_sftp = MagicMock() mock_ssh.open_sftp.return_value = mock_sftp - + # Simulate directories not existing mock_sftp.stat.side_effect = FileNotFoundError mock_ssh_class.return_value = mock_ssh @@ -201,7 +200,7 @@ class TestUploadToSFTP: """Test that connections are cleaned up on error.""" test_file = tmp_path / "test.pdf" test_file.write_text("test content") - + mock_settings.sftp_host = "sftp.example.com" mock_settings.sftp_port = 22 mock_settings.sftp_username = "testuser" diff --git a/tests/test_views_license.py b/tests/test_views_license.py index c2b7d571..3fe863f5 100644 --- a/tests/test_views_license.py +++ b/tests/test_views_license.py @@ -1,6 +1,5 @@ """Tests for app/views/license_routes.py module.""" -from pathlib import Path from unittest.mock import mock_open, patch import pytest @@ -19,7 +18,7 @@ class TestLicenseViews: """Test successful LGPL license retrieval.""" # Create a mock license file license_content = "GNU Lesser General Public License\nVersion 3, 29 June 2007" - + with patch("pathlib.Path.exists", return_value=True): with patch("builtins.open", mock_open(read_data=license_content)): response = client.get("/licenses/lgpl.txt") diff --git a/tests/test_views_status.py b/tests/test_views_status.py index 7e70375b..46bef1a9 100644 --- a/tests/test_views_status.py +++ b/tests/test_views_status.py @@ -242,7 +242,9 @@ class TestContainerInfoDetection: @patch("app.views.status.os.path.exists") @patch("builtins.open", side_effect=IOError("Permission denied")) @pytest.mark.asyncio - async def test_handles_cgroup_read_error(self, mock_file, mock_exists, mock_settings, mock_templates, mock_providers): + async def test_handles_cgroup_read_error( + self, mock_file, mock_exists, mock_settings, mock_templates, mock_providers + ): """Test handles cgroup file read errors.""" from app.views.status import status_dashboard @@ -269,7 +271,9 @@ class TestContainerInfoDetection: @patch("app.views.status.os.path.exists") @patch("builtins.open", new_callable=mock_open, read_data="12:cpuset:/system.slice\n13:memory:/user.slice") @pytest.mark.asyncio - async def test_handles_cgroup_without_docker(self, mock_file, mock_exists, mock_settings, mock_templates, mock_providers): + async def test_handles_cgroup_without_docker( + self, mock_file, mock_exists, mock_settings, mock_templates, mock_providers + ): """Test handles cgroup without docker in path.""" from app.views.status import status_dashboard