Fix NFO 503 error on server reload with config fallback

- Add dynamic config loading in get_nfo_service() dependency
- Handle settings reset during uvicorn reload in development
- Add comprehensive tests for settings priority and fallback behavior
- All 4 unit tests passing (settings priority, config fallback, error cases)
- Update documentation with reload scenario fix
This commit is contained in:
2026-01-18 12:16:05 +01:00
parent 4e56093ff9
commit e502dcb8bd
3 changed files with 153 additions and 3 deletions

View File

@@ -0,0 +1,112 @@
"""Tests for NFO service dependency with config fallback.
Tests that get_nfo_service() correctly loads TMDB API key from config.json
when it's not in settings (e.g., after server reload in development).
"""
import pytest
from unittest.mock import MagicMock, patch
from fastapi import HTTPException
from src.server.api.nfo import get_nfo_service
from src.server.models.config import NFOConfig, AppConfig
from src.config.settings import settings
@pytest.mark.asyncio
async def test_get_nfo_service_with_settings_tmdb_key():
"""Test get_nfo_service when TMDB key is in settings."""
# Set TMDB API key in settings
original_key = settings.tmdb_api_key
settings.tmdb_api_key = "test_api_key_from_settings"
try:
nfo_service = await get_nfo_service()
assert nfo_service is not None
assert nfo_service.tmdb_client.api_key == "test_api_key_from_settings"
finally:
settings.tmdb_api_key = original_key
@pytest.mark.asyncio
async def test_get_nfo_service_fallback_to_config():
"""Test get_nfo_service falls back to config.json when key not in settings."""
# Clear TMDB API key from settings
original_key = settings.tmdb_api_key
settings.tmdb_api_key = None
try:
# Mock config service to return NFO config with API key
mock_config = AppConfig(
name="Test",
data_dir="data",
nfo=NFOConfig(
tmdb_api_key="test_api_key_from_config",
auto_create=False,
update_on_scan=False
)
)
with patch('src.server.services.config_service.get_config_service') as mock_get_config:
mock_config_service = MagicMock()
mock_config_service.load_config.return_value = mock_config
mock_get_config.return_value = mock_config_service
nfo_service = await get_nfo_service()
assert nfo_service is not None
assert nfo_service.tmdb_client.api_key == "test_api_key_from_config"
finally:
settings.tmdb_api_key = original_key
@pytest.mark.asyncio
async def test_get_nfo_service_no_key_raises_503():
"""Test get_nfo_service raises 503 when no TMDB key available."""
# Clear TMDB API key from settings
original_key = settings.tmdb_api_key
settings.tmdb_api_key = None
try:
# Mock config service to return config without API key
mock_config = AppConfig(
name="Test",
data_dir="data",
nfo=NFOConfig(
tmdb_api_key=None,
auto_create=False,
update_on_scan=False
)
)
with patch('src.server.services.config_service.get_config_service') as mock_get_config:
mock_config_service = MagicMock()
mock_config_service.load_config.return_value = mock_config
mock_get_config.return_value = mock_config_service
with pytest.raises(HTTPException) as exc_info:
await get_nfo_service()
assert exc_info.value.status_code == 503
assert "TMDB API key required" in exc_info.value.detail
finally:
settings.tmdb_api_key = original_key
@pytest.mark.asyncio
async def test_get_nfo_service_config_load_fails_raises_503():
"""Test get_nfo_service raises 503 when config loading fails."""
# Clear TMDB API key from settings
original_key = settings.tmdb_api_key
settings.tmdb_api_key = None
try:
# Mock config service to raise exception
with patch('src.server.services.config_service.get_config_service') as mock_get_config:
mock_get_config.side_effect = Exception("Config file not found")
with pytest.raises(HTTPException) as exc_info:
await get_nfo_service()
assert exc_info.value.status_code == 503
assert "TMDB API key required" in exc_info.value.detail
finally:
settings.tmdb_api_key = original_key