feat: add legacy key/data file migration to database
- Add migration_legacy_files_completed flag to SystemSettings model - Create legacy_file_migration service to migrate series from key/data files - Integrate legacy migration into initialization_service startup flow - Add integration tests for legacy file migration - Update DATABASE.md documentation with migration details - Fix various test and service issues (nfo_repair, tmdb_client, download_service) - Add test_database_schema unit tests
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
"""Unit tests for ffmpeg health check in fastapi_app.py."""
|
||||
|
||||
import asyncio
|
||||
from unittest.mock import MagicMock, patch
|
||||
from unittest.mock import MagicMock, patch, AsyncMock
|
||||
|
||||
import pytest
|
||||
|
||||
@@ -12,43 +12,75 @@ class TestFfmpegHealthCheck:
|
||||
@pytest.mark.asyncio
|
||||
async def test_ffmpeg_missing_warns(self):
|
||||
"""Should log warning when ffmpeg not found in PATH."""
|
||||
mock_logger = MagicMock()
|
||||
mock_logger.warning = MagicMock()
|
||||
mock_logger.info = MagicMock()
|
||||
mock_logger.debug = MagicMock()
|
||||
|
||||
with patch("shutil.which", return_value=None):
|
||||
with patch("src.server.fastapi_app.setup_logging") as mock_log:
|
||||
mock_logger = MagicMock()
|
||||
mock_log.return_value = mock_logger
|
||||
with patch("src.server.fastapi_app.setup_logging", return_value=mock_logger):
|
||||
# Patch service getters at their actual definition modules
|
||||
with patch("src.server.services.config_service.get_config_service"):
|
||||
with patch("src.server.services.progress_service.get_progress_service"):
|
||||
with patch("src.server.services.websocket_service.get_websocket_service"):
|
||||
with patch("src.server.utils.dependencies.get_anime_service"):
|
||||
with patch("src.server.utils.dependencies.get_download_service"):
|
||||
with patch("src.server.utils.dependencies.get_background_loader_service"):
|
||||
with patch("src.server.services.scheduler_service.get_scheduler_service") as mock_get_sched:
|
||||
mock_sched = MagicMock()
|
||||
mock_sched.start = AsyncMock(return_value=None)
|
||||
mock_get_sched.return_value = mock_sched
|
||||
with patch("src.server.database.connection.init_db", new_callable=AsyncMock):
|
||||
with patch("src.server.services.initialization_service.perform_initial_setup", new_callable=AsyncMock):
|
||||
with patch("src.server.services.initialization_service.perform_nfo_scan_if_needed", new_callable=AsyncMock):
|
||||
with patch("src.server.services.initialization_service.perform_media_scan_if_needed", new_callable=AsyncMock):
|
||||
from src.server.fastapi_app import lifespan
|
||||
app = MagicMock()
|
||||
|
||||
from src.server.fastapi_app import lifespan
|
||||
app = MagicMock()
|
||||
async with lifespan(app):
|
||||
pass
|
||||
|
||||
with pytest.raises(StopIteration):
|
||||
async with lifespan(app):
|
||||
pass
|
||||
|
||||
# Should have logged a warning about ffmpeg
|
||||
warning_calls = [
|
||||
c for c in mock_logger.warning.call_args_list
|
||||
if "ffmpeg" in str(c)
|
||||
]
|
||||
assert len(warning_calls) >= 1
|
||||
# Should have logged a warning about ffmpeg
|
||||
warning_calls = [
|
||||
c for c in mock_logger.warning.call_args_list
|
||||
if "ffmpeg" in str(c)
|
||||
]
|
||||
assert len(warning_calls) >= 1
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_ffmpeg_present_no_warning(self):
|
||||
"""Should not log warning when ffmpeg is found."""
|
||||
mock_logger = MagicMock()
|
||||
mock_logger.warning = MagicMock()
|
||||
mock_logger.info = MagicMock()
|
||||
mock_logger.debug = MagicMock()
|
||||
|
||||
with patch("shutil.which", return_value="/usr/bin/ffmpeg"):
|
||||
with patch("src.server.fastapi_app.setup_logging") as mock_log:
|
||||
mock_logger = MagicMock()
|
||||
mock_log.return_value = mock_logger
|
||||
with patch("src.server.fastapi_app.setup_logging", return_value=mock_logger):
|
||||
# Patch service getters at their actual definition modules
|
||||
with patch("src.server.services.config_service.get_config_service"):
|
||||
with patch("src.server.services.progress_service.get_progress_service"):
|
||||
with patch("src.server.services.websocket_service.get_websocket_service"):
|
||||
with patch("src.server.utils.dependencies.get_anime_service"):
|
||||
with patch("src.server.utils.dependencies.get_download_service"):
|
||||
with patch("src.server.utils.dependencies.get_background_loader_service"):
|
||||
with patch("src.server.services.scheduler_service.get_scheduler_service") as mock_get_sched:
|
||||
mock_sched = MagicMock()
|
||||
mock_sched.start = AsyncMock(return_value=None)
|
||||
mock_get_sched.return_value = mock_sched
|
||||
with patch("src.server.database.connection.init_db", new_callable=AsyncMock):
|
||||
with patch("src.server.services.initialization_service.perform_initial_setup", new_callable=AsyncMock):
|
||||
with patch("src.server.services.initialization_service.perform_nfo_scan_if_needed", new_callable=AsyncMock):
|
||||
with patch("src.server.services.initialization_service.perform_media_scan_if_needed", new_callable=AsyncMock):
|
||||
from src.server.fastapi_app import lifespan
|
||||
app = MagicMock()
|
||||
|
||||
from src.server.fastapi_app import lifespan
|
||||
app = MagicMock()
|
||||
async with lifespan(app):
|
||||
pass
|
||||
|
||||
with pytest.raises(StopIteration):
|
||||
async with lifespan(app):
|
||||
pass
|
||||
|
||||
# Should NOT have logged a warning about ffmpeg
|
||||
warning_calls = [
|
||||
c for c in mock_logger.warning.call_args_list
|
||||
if "ffmpeg" in str(c)
|
||||
]
|
||||
assert len(warning_calls) == 0
|
||||
# Should NOT have logged a warning about ffmpeg
|
||||
warning_calls = [
|
||||
c for c in mock_logger.warning.call_args_list
|
||||
if "ffmpeg" in str(c)
|
||||
]
|
||||
assert len(warning_calls) == 0
|
||||
Reference in New Issue
Block a user