- Remove NFO repair scan step from ARCHITECTURE.md startup sequence - Update CHANGELOG.md: rephrase perform_nfo_repair_scan as scheduled scan - Add test verifying perform_nfo_repair_scan is NOT called in lifespan - Keep existing folder scan wiring tests and unit tests intact - NFO_GUIDE.md already correctly describes scheduled scan behavior
110 lines
4.2 KiB
Python
110 lines
4.2 KiB
Python
"""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(
|
|
"<tvshow><title>Attack on Titan</title><year>2013</year></tvshow>"
|
|
)
|
|
|
|
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()
|