Task 6: Add CLI Interface tests (25 tests)
- test_nfo_cli.py: 19 tests for main dispatcher (scan/status/update/unknown), scan_and_create_nfo, check_nfo_status, update_nfo_files - test_cli_workflows.py: 6 integration tests for end-to-end scan workflow, update workflow, error handling, and per-series error continuation
This commit is contained in:
184
tests/integration/test_cli_workflows.py
Normal file
184
tests/integration/test_cli_workflows.py
Normal file
@@ -0,0 +1,184 @@
|
||||
"""Integration tests for CLI workflows.
|
||||
|
||||
Tests end-to-end CLI command execution using subprocess-style invocation of
|
||||
the nfo_cli main() function with mocked services.
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from src.cli.nfo_cli import main, scan_and_create_nfo, update_nfo_files
|
||||
|
||||
|
||||
def _mock_serie(name: str, has_nfo: bool = False):
|
||||
"""Create a mock serie object."""
|
||||
s = MagicMock()
|
||||
s.name = name
|
||||
s.folder = name
|
||||
s.has_nfo.return_value = has_nfo
|
||||
s.has_poster.return_value = False
|
||||
s.has_logo.return_value = False
|
||||
s.has_fanart.return_value = False
|
||||
return s
|
||||
|
||||
|
||||
class TestScanWorkflow:
|
||||
"""End-to-end scan workflow."""
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch("src.cli.nfo_cli.SeriesManagerService")
|
||||
@patch("src.cli.nfo_cli.settings")
|
||||
async def test_scan_creates_nfo_and_closes(self, mock_settings, mock_sms):
|
||||
"""Full scan workflow: init → scan → close."""
|
||||
mock_settings.tmdb_api_key = "key"
|
||||
mock_settings.anime_directory = "/anime"
|
||||
mock_settings.nfo_auto_create = True
|
||||
mock_settings.nfo_update_on_scan = False
|
||||
mock_settings.nfo_download_poster = False
|
||||
mock_settings.nfo_download_logo = False
|
||||
mock_settings.nfo_download_fanart = False
|
||||
|
||||
series = [_mock_serie("Naruto"), _mock_serie("Bleach")]
|
||||
mock_serie_list = MagicMock()
|
||||
mock_serie_list.get_all.return_value = series
|
||||
mock_serie_list.load_series = MagicMock()
|
||||
|
||||
manager = MagicMock()
|
||||
manager.get_serie_list.return_value = mock_serie_list
|
||||
manager.scan_and_process_nfo = AsyncMock()
|
||||
manager.close = AsyncMock()
|
||||
mock_sms.from_settings.return_value = manager
|
||||
|
||||
result = await scan_and_create_nfo()
|
||||
|
||||
assert result == 0
|
||||
manager.scan_and_process_nfo.assert_awaited_once()
|
||||
manager.close.assert_awaited_once()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch("src.cli.nfo_cli.SeriesManagerService")
|
||||
@patch("src.cli.nfo_cli.settings")
|
||||
async def test_scan_all_have_nfo_and_no_update(self, mock_settings, mock_sms):
|
||||
"""When all series have NFO and update_on_scan is False, returns 0 early."""
|
||||
mock_settings.tmdb_api_key = "key"
|
||||
mock_settings.anime_directory = "/anime"
|
||||
mock_settings.nfo_auto_create = True
|
||||
mock_settings.nfo_update_on_scan = False
|
||||
mock_settings.nfo_download_poster = False
|
||||
mock_settings.nfo_download_logo = False
|
||||
mock_settings.nfo_download_fanart = False
|
||||
|
||||
series = [_mock_serie("Naruto", has_nfo=True)]
|
||||
mock_serie_list = MagicMock()
|
||||
mock_serie_list.get_all.return_value = series
|
||||
|
||||
manager = MagicMock()
|
||||
manager.get_serie_list.return_value = mock_serie_list
|
||||
mock_sms.from_settings.return_value = manager
|
||||
|
||||
result = await scan_and_create_nfo()
|
||||
assert result == 0
|
||||
|
||||
|
||||
class TestUpdateWorkflow:
|
||||
"""End-to-end update workflow."""
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch("src.cli.nfo_cli.asyncio")
|
||||
@patch("src.cli.nfo_cli.settings")
|
||||
async def test_update_processes_each_serie(self, mock_settings, mock_sleeper):
|
||||
"""Update calls update_tvshow_nfo for every serie with NFO."""
|
||||
mock_settings.tmdb_api_key = "key"
|
||||
mock_settings.anime_directory = "/anime"
|
||||
mock_settings.nfo_download_poster = True
|
||||
mock_settings.nfo_download_logo = False
|
||||
mock_settings.nfo_download_fanart = False
|
||||
mock_sleeper.sleep = AsyncMock()
|
||||
|
||||
series = [
|
||||
_mock_serie("A", has_nfo=True),
|
||||
_mock_serie("B", has_nfo=True),
|
||||
_mock_serie("C", has_nfo=False),
|
||||
]
|
||||
|
||||
nfo_svc = MagicMock()
|
||||
nfo_svc.update_tvshow_nfo = AsyncMock()
|
||||
nfo_svc.close = AsyncMock()
|
||||
|
||||
with patch("src.core.entities.SerieList.SerieList") as mock_sl:
|
||||
mock_list = MagicMock()
|
||||
mock_list.get_all.return_value = series
|
||||
mock_sl.return_value = mock_list
|
||||
with patch(
|
||||
"src.core.services.nfo_factory.create_nfo_service",
|
||||
return_value=nfo_svc,
|
||||
):
|
||||
result = await update_nfo_files()
|
||||
|
||||
assert result == 0
|
||||
# Only A and B have NFO
|
||||
assert nfo_svc.update_tvshow_nfo.await_count == 2
|
||||
nfo_svc.close.assert_awaited_once()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch("src.cli.nfo_cli.asyncio")
|
||||
@patch("src.cli.nfo_cli.settings")
|
||||
async def test_update_continues_on_per_series_error(
|
||||
self, mock_settings, mock_sleeper
|
||||
):
|
||||
"""An error updating one serie doesn't stop others."""
|
||||
mock_settings.tmdb_api_key = "key"
|
||||
mock_settings.anime_directory = "/anime"
|
||||
mock_settings.nfo_download_poster = False
|
||||
mock_settings.nfo_download_logo = False
|
||||
mock_settings.nfo_download_fanart = False
|
||||
mock_sleeper.sleep = AsyncMock()
|
||||
|
||||
series = [
|
||||
_mock_serie("OK", has_nfo=True),
|
||||
_mock_serie("Fail", has_nfo=True),
|
||||
]
|
||||
|
||||
nfo_svc = MagicMock()
|
||||
# First call succeeds, second raises
|
||||
nfo_svc.update_tvshow_nfo = AsyncMock(
|
||||
side_effect=[None, RuntimeError("api down")]
|
||||
)
|
||||
nfo_svc.close = AsyncMock()
|
||||
|
||||
with patch("src.core.entities.SerieList.SerieList") as mock_sl:
|
||||
mock_list = MagicMock()
|
||||
mock_list.get_all.return_value = series
|
||||
mock_sl.return_value = mock_list
|
||||
with patch(
|
||||
"src.core.services.nfo_factory.create_nfo_service",
|
||||
return_value=nfo_svc,
|
||||
):
|
||||
result = await update_nfo_files()
|
||||
|
||||
assert result == 0
|
||||
assert nfo_svc.update_tvshow_nfo.await_count == 2
|
||||
|
||||
|
||||
class TestErrorHandlingWorkflows:
|
||||
"""Test error paths in CLI workflows."""
|
||||
|
||||
@patch("src.cli.nfo_cli.sys")
|
||||
def test_main_usage_printed_on_no_args(self, mock_sys, capsys):
|
||||
"""Shows usage and returns 1 with no args."""
|
||||
mock_sys.argv = ["nfo_cli"]
|
||||
result = main()
|
||||
assert result == 1
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch("src.cli.nfo_cli.settings")
|
||||
async def test_missing_config_returns_1(self, mock_settings):
|
||||
"""Missing required settings yields exit code 1."""
|
||||
mock_settings.tmdb_api_key = None
|
||||
assert await scan_and_create_nfo() == 1
|
||||
|
||||
mock_settings.tmdb_api_key = "key"
|
||||
mock_settings.anime_directory = None
|
||||
assert await scan_and_create_nfo() == 1
|
||||
357
tests/unit/test_nfo_cli.py
Normal file
357
tests/unit/test_nfo_cli.py
Normal file
@@ -0,0 +1,357 @@
|
||||
"""Unit tests for the NFO CLI module.
|
||||
|
||||
Tests the CLI entry point, command dispatch, and individual command functions
|
||||
from src/cli/nfo_cli.py.
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
from io import StringIO
|
||||
from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from src.cli.nfo_cli import (
|
||||
check_nfo_status,
|
||||
main,
|
||||
scan_and_create_nfo,
|
||||
update_nfo_files,
|
||||
)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# main() dispatcher tests
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
class TestMainDispatcher:
|
||||
"""Tests for the main() CLI entry point."""
|
||||
|
||||
@patch("src.cli.nfo_cli.sys")
|
||||
def test_no_args_shows_usage(self, mock_sys, capsys):
|
||||
"""No arguments prints usage text and returns 1."""
|
||||
mock_sys.argv = ["nfo_cli"]
|
||||
result = main()
|
||||
assert result == 1
|
||||
|
||||
@patch("src.cli.nfo_cli.asyncio")
|
||||
@patch("src.cli.nfo_cli.sys")
|
||||
def test_scan_command_dispatches(self, mock_sys, mock_asyncio):
|
||||
"""'scan' command runs scan_and_create_nfo."""
|
||||
mock_sys.argv = ["nfo_cli", "scan"]
|
||||
mock_asyncio.run.return_value = 0
|
||||
result = main()
|
||||
mock_asyncio.run.assert_called_once()
|
||||
|
||||
@patch("src.cli.nfo_cli.asyncio")
|
||||
@patch("src.cli.nfo_cli.sys")
|
||||
def test_status_command_dispatches(self, mock_sys, mock_asyncio):
|
||||
"""'status' command runs check_nfo_status."""
|
||||
mock_sys.argv = ["nfo_cli", "status"]
|
||||
mock_asyncio.run.return_value = 0
|
||||
result = main()
|
||||
mock_asyncio.run.assert_called_once()
|
||||
|
||||
@patch("src.cli.nfo_cli.asyncio")
|
||||
@patch("src.cli.nfo_cli.sys")
|
||||
def test_update_command_dispatches(self, mock_sys, mock_asyncio):
|
||||
"""'update' command runs update_nfo_files."""
|
||||
mock_sys.argv = ["nfo_cli", "update"]
|
||||
mock_asyncio.run.return_value = 0
|
||||
result = main()
|
||||
mock_asyncio.run.assert_called_once()
|
||||
|
||||
@patch("src.cli.nfo_cli.sys")
|
||||
def test_unknown_command_returns_1(self, mock_sys):
|
||||
"""Unknown command returns exit code 1."""
|
||||
mock_sys.argv = ["nfo_cli", "bogus"]
|
||||
result = main()
|
||||
assert result == 1
|
||||
|
||||
@patch("src.cli.nfo_cli.asyncio")
|
||||
@patch("src.cli.nfo_cli.sys")
|
||||
def test_command_is_case_insensitive(self, mock_sys, mock_asyncio):
|
||||
"""Command matching is case-insensitive."""
|
||||
mock_sys.argv = ["nfo_cli", "SCAN"]
|
||||
mock_asyncio.run.return_value = 0
|
||||
main()
|
||||
mock_asyncio.run.assert_called_once()
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# scan_and_create_nfo tests
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
class TestScanAndCreateNfo:
|
||||
"""Tests for scan_and_create_nfo command."""
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch("src.cli.nfo_cli.settings")
|
||||
async def test_returns_1_without_tmdb_key(self, mock_settings):
|
||||
"""Returns 1 when TMDB_API_KEY is missing."""
|
||||
mock_settings.tmdb_api_key = None
|
||||
result = await scan_and_create_nfo()
|
||||
assert result == 1
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch("src.cli.nfo_cli.settings")
|
||||
async def test_returns_1_without_anime_directory(self, mock_settings):
|
||||
"""Returns 1 when ANIME_DIRECTORY is missing."""
|
||||
mock_settings.tmdb_api_key = "key"
|
||||
mock_settings.anime_directory = None
|
||||
result = await scan_and_create_nfo()
|
||||
assert result == 1
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch("src.cli.nfo_cli.SeriesManagerService")
|
||||
@patch("src.cli.nfo_cli.settings")
|
||||
async def test_returns_0_when_no_series_found(self, mock_settings, mock_sms):
|
||||
"""Returns 0 when directory has no series."""
|
||||
mock_settings.tmdb_api_key = "key"
|
||||
mock_settings.anime_directory = "/anime"
|
||||
mock_settings.nfo_auto_create = True
|
||||
mock_settings.nfo_update_on_scan = False
|
||||
mock_settings.nfo_download_poster = False
|
||||
mock_settings.nfo_download_logo = False
|
||||
mock_settings.nfo_download_fanart = False
|
||||
|
||||
mock_manager = MagicMock()
|
||||
mock_serie_list = MagicMock()
|
||||
mock_serie_list.get_all.return_value = []
|
||||
mock_manager.get_serie_list.return_value = mock_serie_list
|
||||
mock_sms.from_settings.return_value = mock_manager
|
||||
|
||||
result = await scan_and_create_nfo()
|
||||
assert result == 0
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch("src.cli.nfo_cli.SeriesManagerService")
|
||||
@patch("src.cli.nfo_cli.settings")
|
||||
async def test_calls_scan_and_process_nfo(self, mock_settings, mock_sms):
|
||||
"""Processing is invoked for found series."""
|
||||
mock_settings.tmdb_api_key = "key"
|
||||
mock_settings.anime_directory = "/anime"
|
||||
mock_settings.nfo_auto_create = True
|
||||
mock_settings.nfo_update_on_scan = False
|
||||
mock_settings.nfo_download_poster = False
|
||||
mock_settings.nfo_download_logo = False
|
||||
mock_settings.nfo_download_fanart = False
|
||||
|
||||
mock_serie = MagicMock()
|
||||
mock_serie.has_nfo.return_value = False
|
||||
mock_serie.name = "Naruto"
|
||||
mock_serie.folder = "Naruto"
|
||||
mock_serie.has_poster.return_value = False
|
||||
mock_serie.has_logo.return_value = False
|
||||
mock_serie.has_fanart.return_value = False
|
||||
|
||||
mock_serie_list = MagicMock()
|
||||
mock_serie_list.get_all.return_value = [mock_serie]
|
||||
mock_serie_list.load_series = MagicMock()
|
||||
|
||||
mock_manager = MagicMock()
|
||||
mock_manager.get_serie_list.return_value = mock_serie_list
|
||||
mock_manager.scan_and_process_nfo = AsyncMock()
|
||||
mock_manager.close = AsyncMock()
|
||||
mock_sms.from_settings.return_value = mock_manager
|
||||
|
||||
result = await scan_and_create_nfo()
|
||||
assert result == 0
|
||||
mock_manager.scan_and_process_nfo.assert_awaited_once()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch("src.cli.nfo_cli.SeriesManagerService")
|
||||
@patch("src.cli.nfo_cli.settings")
|
||||
async def test_returns_1_on_exception(self, mock_settings, mock_sms):
|
||||
"""Returns 1 when processing raises."""
|
||||
mock_settings.tmdb_api_key = "key"
|
||||
mock_settings.anime_directory = "/anime"
|
||||
mock_settings.nfo_auto_create = True
|
||||
mock_settings.nfo_update_on_scan = False
|
||||
mock_settings.nfo_download_poster = False
|
||||
mock_settings.nfo_download_logo = False
|
||||
mock_settings.nfo_download_fanart = False
|
||||
|
||||
mock_serie = MagicMock()
|
||||
mock_serie.has_nfo.return_value = False
|
||||
mock_serie.name = "Test"
|
||||
mock_serie.folder = "Test"
|
||||
mock_serie_list = MagicMock()
|
||||
mock_serie_list.get_all.return_value = [mock_serie]
|
||||
|
||||
mock_manager = MagicMock()
|
||||
mock_manager.get_serie_list.return_value = mock_serie_list
|
||||
mock_manager.scan_and_process_nfo = AsyncMock(
|
||||
side_effect=RuntimeError("fail")
|
||||
)
|
||||
mock_manager.close = AsyncMock()
|
||||
mock_sms.from_settings.return_value = mock_manager
|
||||
|
||||
result = await scan_and_create_nfo()
|
||||
assert result == 1
|
||||
# close is called even on error (finally block)
|
||||
mock_manager.close.assert_awaited_once()
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# check_nfo_status tests
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
class TestCheckNfoStatus:
|
||||
"""Tests for check_nfo_status command."""
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch("src.cli.nfo_cli.settings")
|
||||
async def test_returns_1_without_anime_directory(self, mock_settings):
|
||||
"""Returns 1 when ANIME_DIRECTORY is missing."""
|
||||
mock_settings.anime_directory = None
|
||||
result = await check_nfo_status()
|
||||
assert result == 1
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch("src.cli.nfo_cli.settings")
|
||||
async def test_returns_0_when_no_series(self, mock_settings):
|
||||
"""Returns 0 when no series found."""
|
||||
mock_settings.anime_directory = "/anime"
|
||||
with patch("src.core.entities.SerieList.SerieList") as mock_sl:
|
||||
mock_list = MagicMock()
|
||||
mock_list.get_all.return_value = []
|
||||
mock_sl.return_value = mock_list
|
||||
result = await check_nfo_status()
|
||||
assert result == 0
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch("src.cli.nfo_cli.settings")
|
||||
async def test_reports_series_with_and_without_nfo(self, mock_settings, capsys):
|
||||
"""Status report categorises series correctly."""
|
||||
mock_settings.anime_directory = "/anime"
|
||||
|
||||
serie_a = MagicMock()
|
||||
serie_a.has_nfo.return_value = True
|
||||
serie_a.has_poster.return_value = True
|
||||
serie_a.has_logo.return_value = False
|
||||
serie_a.has_fanart.return_value = False
|
||||
serie_a.name = "A"
|
||||
serie_a.folder = "A"
|
||||
|
||||
serie_b = MagicMock()
|
||||
serie_b.has_nfo.return_value = False
|
||||
serie_b.has_poster.return_value = False
|
||||
serie_b.has_logo.return_value = False
|
||||
serie_b.has_fanart.return_value = False
|
||||
serie_b.name = "B"
|
||||
serie_b.folder = "B"
|
||||
|
||||
with patch(
|
||||
"src.core.entities.SerieList.SerieList"
|
||||
) as mock_sl:
|
||||
mock_list = MagicMock()
|
||||
mock_list.get_all.return_value = [serie_a, serie_b]
|
||||
mock_sl.return_value = mock_list
|
||||
result = await check_nfo_status()
|
||||
|
||||
assert result == 0
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# update_nfo_files tests
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
class TestUpdateNfoFiles:
|
||||
"""Tests for update_nfo_files command."""
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch("src.cli.nfo_cli.settings")
|
||||
async def test_returns_1_without_tmdb_key(self, mock_settings):
|
||||
"""Returns 1 when TMDB_API_KEY is missing."""
|
||||
mock_settings.tmdb_api_key = None
|
||||
result = await update_nfo_files()
|
||||
assert result == 1
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch("src.cli.nfo_cli.settings")
|
||||
async def test_returns_1_without_anime_directory(self, mock_settings):
|
||||
"""Returns 1 when ANIME_DIRECTORY is missing."""
|
||||
mock_settings.tmdb_api_key = "key"
|
||||
mock_settings.anime_directory = None
|
||||
result = await update_nfo_files()
|
||||
assert result == 1
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch("src.cli.nfo_cli.settings")
|
||||
async def test_returns_0_when_no_nfo_series(self, mock_settings):
|
||||
"""Returns 0 when no series have NFO files."""
|
||||
mock_settings.tmdb_api_key = "key"
|
||||
mock_settings.anime_directory = "/anime"
|
||||
mock_settings.nfo_download_poster = False
|
||||
mock_settings.nfo_download_logo = False
|
||||
mock_settings.nfo_download_fanart = False
|
||||
|
||||
serie = MagicMock()
|
||||
serie.has_nfo.return_value = False
|
||||
|
||||
with patch("src.core.entities.SerieList.SerieList") as mock_sl:
|
||||
mock_list = MagicMock()
|
||||
mock_list.get_all.return_value = [serie]
|
||||
mock_sl.return_value = mock_list
|
||||
result = await update_nfo_files()
|
||||
|
||||
assert result == 0
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch("src.cli.nfo_cli.asyncio")
|
||||
@patch("src.cli.nfo_cli.settings")
|
||||
async def test_updates_series_with_nfo(self, mock_settings, mock_sleeper):
|
||||
"""Calls update_tvshow_nfo for each series with NFO."""
|
||||
mock_settings.tmdb_api_key = "key"
|
||||
mock_settings.anime_directory = "/anime"
|
||||
mock_settings.nfo_download_poster = True
|
||||
mock_settings.nfo_download_logo = False
|
||||
mock_settings.nfo_download_fanart = False
|
||||
mock_sleeper.sleep = AsyncMock()
|
||||
|
||||
serie = MagicMock()
|
||||
serie.has_nfo.return_value = True
|
||||
serie.name = "Naruto"
|
||||
serie.folder = "Naruto"
|
||||
|
||||
mock_nfo_svc = MagicMock()
|
||||
mock_nfo_svc.update_tvshow_nfo = AsyncMock()
|
||||
mock_nfo_svc.close = AsyncMock()
|
||||
|
||||
with patch("src.core.entities.SerieList.SerieList") as mock_sl:
|
||||
mock_list = MagicMock()
|
||||
mock_list.get_all.return_value = [serie]
|
||||
mock_sl.return_value = mock_list
|
||||
with patch(
|
||||
"src.core.services.nfo_factory.create_nfo_service",
|
||||
return_value=mock_nfo_svc,
|
||||
):
|
||||
result = await update_nfo_files()
|
||||
|
||||
assert result == 0
|
||||
mock_nfo_svc.update_tvshow_nfo.assert_awaited_once()
|
||||
mock_nfo_svc.close.assert_awaited_once()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch("src.cli.nfo_cli.settings")
|
||||
async def test_returns_1_on_factory_error(self, mock_settings):
|
||||
"""Returns 1 when create_nfo_service raises ValueError."""
|
||||
mock_settings.tmdb_api_key = "key"
|
||||
mock_settings.anime_directory = "/anime"
|
||||
mock_settings.nfo_download_poster = False
|
||||
mock_settings.nfo_download_logo = False
|
||||
mock_settings.nfo_download_fanart = False
|
||||
|
||||
serie = MagicMock()
|
||||
serie.has_nfo.return_value = True
|
||||
|
||||
with patch("src.core.entities.SerieList.SerieList") as mock_sl:
|
||||
mock_list = MagicMock()
|
||||
mock_list.get_all.return_value = [serie]
|
||||
mock_sl.return_value = mock_list
|
||||
with patch(
|
||||
"src.core.services.nfo_factory.create_nfo_service",
|
||||
side_effect=ValueError("bad"),
|
||||
):
|
||||
result = await update_nfo_files()
|
||||
|
||||
assert result == 1
|
||||
Reference in New Issue
Block a user