fix: always repair NFO via update_tvshow_nfo so plot is written

This commit is contained in:
2026-02-22 16:55:54 +01:00
parent 759cd09ded
commit c186e0d4f7
3 changed files with 59 additions and 54 deletions

View File

@@ -48,11 +48,10 @@ class TestNfoRepairScanIntegrationWithBackgroundLoader:
"""Integration test: incomplete NFO series are queued via background_loader."""
@pytest.mark.asyncio
async def test_incomplete_nfo_series_queued(self, tmp_path):
"""Series whose tvshow.nfo is missing required tags get queued."""
async def test_incomplete_nfo_series_scheduled_for_repair(self, tmp_path):
"""Series whose tvshow.nfo is missing required tags are scheduled via asyncio.create_task."""
from src.server.services.initialization_service import perform_nfo_repair_scan
# Create a series directory with a minimal (incomplete) NFO
series_dir = tmp_path / "IncompleteAnime"
series_dir.mkdir()
(series_dir / "tvshow.nfo").write_text(
@@ -63,8 +62,8 @@ class TestNfoRepairScanIntegrationWithBackgroundLoader:
mock_settings.tmdb_api_key = "test-key"
mock_settings.anime_directory = str(tmp_path)
mock_loader = AsyncMock()
mock_loader.add_series_loading_task = AsyncMock()
mock_repair_service = AsyncMock()
mock_repair_service.repair_series = AsyncMock(return_value=True)
with patch(
"src.server.services.initialization_service.settings", mock_settings
@@ -73,19 +72,20 @@ class TestNfoRepairScanIntegrationWithBackgroundLoader:
return_value=True,
), patch(
"src.core.services.nfo_factory.NFOServiceFactory"
) as mock_factory:
) as mock_factory, patch(
"src.core.services.nfo_repair_service.NfoRepairService",
return_value=mock_repair_service,
), patch(
"asyncio.create_task"
) as mock_create_task:
mock_factory.return_value.create.return_value = MagicMock()
await perform_nfo_repair_scan(background_loader=mock_loader)
await perform_nfo_repair_scan(background_loader=AsyncMock())
mock_loader.add_series_loading_task.assert_called_once_with(
key="IncompleteAnime",
folder="IncompleteAnime",
name="IncompleteAnime",
)
mock_create_task.assert_called_once()
@pytest.mark.asyncio
async def test_complete_nfo_series_not_queued(self, tmp_path):
"""Series whose tvshow.nfo has all required tags are not queued."""
async def test_complete_nfo_series_not_scheduled(self, tmp_path):
"""Series whose tvshow.nfo has all required tags are not scheduled for repair."""
from src.server.services.initialization_service import perform_nfo_repair_scan
series_dir = tmp_path / "CompleteAnime"
@@ -98,9 +98,6 @@ class TestNfoRepairScanIntegrationWithBackgroundLoader:
mock_settings.tmdb_api_key = "test-key"
mock_settings.anime_directory = str(tmp_path)
mock_loader = AsyncMock()
mock_loader.add_series_loading_task = AsyncMock()
with patch(
"src.server.services.initialization_service.settings", mock_settings
), patch(
@@ -108,8 +105,10 @@ class TestNfoRepairScanIntegrationWithBackgroundLoader:
return_value=False,
), patch(
"src.core.services.nfo_factory.NFOServiceFactory"
) as mock_factory:
) as mock_factory, patch(
"asyncio.create_task"
) as mock_create_task:
mock_factory.return_value.create.return_value = MagicMock()
await perform_nfo_repair_scan(background_loader=mock_loader)
await perform_nfo_repair_scan(background_loader=AsyncMock())
mock_loader.add_series_loading_task.assert_not_called()
mock_create_task.assert_not_called()

View File

@@ -790,9 +790,8 @@ class TestPerformNfoRepairScan:
await perform_nfo_repair_scan()
@pytest.mark.asyncio
async def test_queues_deficient_series_via_background_loader(self, tmp_path):
"""Series with incomplete NFO should be queued via background_loader."""
# Create a fake series directory with a tvshow.nfo file
async def test_queues_deficient_series_as_asyncio_task(self, tmp_path):
"""Series with incomplete NFO should be scheduled via asyncio.create_task."""
series_dir = tmp_path / "MyAnime"
series_dir.mkdir()
nfo_file = series_dir / "tvshow.nfo"
@@ -802,8 +801,8 @@ class TestPerformNfoRepairScan:
mock_settings.tmdb_api_key = "test-key"
mock_settings.anime_directory = str(tmp_path)
mock_background_loader = AsyncMock()
mock_background_loader.add_series_loading_task = AsyncMock()
mock_repair_service = AsyncMock()
mock_repair_service.repair_series = AsyncMock(return_value=True)
with patch(
"src.server.services.initialization_service.settings", mock_settings
@@ -812,17 +811,20 @@ class TestPerformNfoRepairScan:
return_value=True,
), patch(
"src.core.services.nfo_factory.NFOServiceFactory"
) as mock_factory_cls:
) as mock_factory_cls, patch(
"src.core.services.nfo_repair_service.NfoRepairService",
return_value=mock_repair_service,
), patch(
"asyncio.create_task"
) as mock_create_task:
mock_factory_cls.return_value.create.return_value = MagicMock()
await perform_nfo_repair_scan(background_loader=mock_background_loader)
await perform_nfo_repair_scan(background_loader=AsyncMock())
mock_background_loader.add_series_loading_task.assert_called_once_with(
key="MyAnime", folder="MyAnime", name="MyAnime"
)
mock_create_task.assert_called_once()
@pytest.mark.asyncio
async def test_skips_complete_series(self, tmp_path):
"""Series with complete NFO should not be queued or repaired."""
"""Series with complete NFO should not be scheduled for repair."""
series_dir = tmp_path / "CompleteAnime"
series_dir.mkdir()
nfo_file = series_dir / "tvshow.nfo"
@@ -832,9 +834,6 @@ class TestPerformNfoRepairScan:
mock_settings.tmdb_api_key = "test-key"
mock_settings.anime_directory = str(tmp_path)
mock_background_loader = AsyncMock()
mock_background_loader.add_series_loading_task = AsyncMock()
with patch(
"src.server.services.initialization_service.settings", mock_settings
), patch(
@@ -842,15 +841,17 @@ class TestPerformNfoRepairScan:
return_value=False,
), patch(
"src.core.services.nfo_factory.NFOServiceFactory"
) as mock_factory_cls:
) as mock_factory_cls, patch(
"asyncio.create_task"
) as mock_create_task:
mock_factory_cls.return_value.create.return_value = MagicMock()
await perform_nfo_repair_scan(background_loader=mock_background_loader)
await perform_nfo_repair_scan(background_loader=AsyncMock())
mock_background_loader.add_series_loading_task.assert_not_called()
mock_create_task.assert_not_called()
@pytest.mark.asyncio
async def test_repairs_directly_without_background_loader(self, tmp_path):
"""When no background_loader provided, repair_series is called directly."""
async def test_repairs_via_asyncio_task_without_background_loader(self, tmp_path):
"""When no background_loader provided, repair is still scheduled via asyncio.create_task."""
series_dir = tmp_path / "NeedsRepair"
series_dir.mkdir()
nfo_file = series_dir / "tvshow.nfo"
@@ -873,8 +874,10 @@ class TestPerformNfoRepairScan:
) as mock_factory_cls, patch(
"src.core.services.nfo_repair_service.NfoRepairService",
return_value=mock_repair_service,
):
), patch(
"asyncio.create_task"
) as mock_create_task:
mock_factory_cls.return_value.create.return_value = MagicMock()
await perform_nfo_repair_scan(background_loader=None)
mock_repair_service.repair_series.assert_called_once()
mock_create_task.assert_called_once()