"""Integration tests for folder rename service wiring. These tests verify that: 1. FolderScanService.run_folder_scan calls validate_and_rename_series_folders. 2. The rename logic is properly integrated into the scheduled folder scan. """ from unittest.mock import AsyncMock, MagicMock, patch import pytest class TestFolderRenameScanCalledInFolderScan: """Verify validate_and_rename_series_folders is invoked from FolderScanService.""" def test_validate_and_rename_imported_in_folder_scan_service(self): """folder_scan_service.py imports validate_and_rename_series_folders.""" import importlib source = importlib.util.find_spec( "src.server.services.folder_scan_service" ).origin with open(source, "r", encoding="utf-8") as fh: content = fh.read() assert "validate_and_rename_series_folders" in content, ( "validate_and_rename_series_folders must be imported in folder_scan_service.py" ) def test_validate_and_rename_called_in_run_folder_scan(self): """validate_and_rename_series_folders must be called inside run_folder_scan.""" import importlib source = importlib.util.find_spec( "src.server.services.folder_scan_service" ).origin with open(source, "r", encoding="utf-8") as fh: content = fh.read() run_folder_scan_pos = content.find("def run_folder_scan") rename_call_pos = content.find("validate_and_rename_series_folders()") assert run_folder_scan_pos != -1, "run_folder_scan method not found" assert rename_call_pos != -1, "validate_and_rename_series_folders call not found" assert rename_call_pos > run_folder_scan_pos, ( "validate_and_rename_series_folders must be called INSIDE run_folder_scan" ) class TestFolderRenameIntegration: """Integration test: folder rename is triggered during folder scan.""" @pytest.mark.asyncio async def test_folder_rename_runs_during_scan(self, tmp_path): """When folder_scan_enabled is true, the scan renames mismatched folders.""" from src.server.services.folder_scan_service import FolderScanService anime_dir = tmp_path / "anime" anime_dir.mkdir() series_dir = anime_dir / "Attack on Titan" series_dir.mkdir() (series_dir / "tvshow.nfo").write_text( "Attack on Titan2013" ) mock_settings = MagicMock() mock_settings.tmdb_api_key = "test-key" mock_settings.anime_directory = str(anime_dir) with patch( "src.config.settings.settings", mock_settings ), patch( "src.server.services.folder_rename_service.settings", mock_settings ), patch( "src.server.services.folder_scan_service.perform_nfo_repair_scan", new_callable=AsyncMock, ), patch( "src.server.services.folder_rename_service._is_series_being_downloaded", return_value=False, ), patch( "src.server.services.folder_rename_service._update_database_paths", new_callable=AsyncMock, ): service = FolderScanService() await service.run_folder_scan() assert not series_dir.exists() assert (anime_dir / "Attack on Titan (2013)").is_dir() @pytest.mark.asyncio async def test_folder_rename_skipped_when_prerequisites_not_met(self, tmp_path): """If anime directory is missing, rename logic is skipped gracefully.""" from src.server.services.folder_scan_service import FolderScanService mock_settings = MagicMock() mock_settings.tmdb_api_key = "test-key" mock_settings.anime_directory = str(tmp_path / "nonexistent") with patch( "src.config.settings.settings", mock_settings ), patch( "src.server.services.folder_scan_service.perform_nfo_repair_scan", new_callable=AsyncMock, ), patch( "src.server.services.folder_rename_service.validate_and_rename_series_folders" ) as mock_rename: service = FolderScanService() await service.run_folder_scan() mock_rename.assert_not_called()