feat(core): Add database support to SeriesApp (Task 7)
- Added db_session parameter to SeriesApp.__init__() - Added db_session property and set_db_session() method - Added init_from_db_async() for async database initialization - Pass db_session to SerieList and SerieScanner during construction - Added get_series_app_with_db() dependency for FastAPI endpoints - All 815 unit tests and 55 API tests pass
This commit is contained in:
@@ -385,3 +385,177 @@ class TestSeriesAppGetters:
|
||||
pass
|
||||
|
||||
|
||||
class TestSeriesAppDatabaseInit:
|
||||
"""Test SeriesApp database initialization."""
|
||||
|
||||
@patch('src.core.SeriesApp.Loaders')
|
||||
@patch('src.core.SeriesApp.SerieScanner')
|
||||
@patch('src.core.SeriesApp.SerieList')
|
||||
def test_init_without_db_session(
|
||||
self, mock_serie_list, mock_scanner, mock_loaders
|
||||
):
|
||||
"""Test SeriesApp initializes without database session."""
|
||||
test_dir = "/test/anime"
|
||||
|
||||
# Create app without db_session
|
||||
app = SeriesApp(test_dir)
|
||||
|
||||
# Verify db_session is None
|
||||
assert app._db_session is None
|
||||
assert app.db_session is None
|
||||
|
||||
# Verify SerieList was called with db_session=None
|
||||
mock_serie_list.assert_called_once()
|
||||
call_kwargs = mock_serie_list.call_args[1]
|
||||
assert call_kwargs.get("db_session") is None
|
||||
|
||||
# Verify SerieScanner was called with db_session=None
|
||||
call_kwargs = mock_scanner.call_args[1]
|
||||
assert call_kwargs.get("db_session") is None
|
||||
|
||||
@patch('src.core.SeriesApp.Loaders')
|
||||
@patch('src.core.SeriesApp.SerieScanner')
|
||||
@patch('src.core.SeriesApp.SerieList')
|
||||
def test_init_with_db_session(
|
||||
self, mock_serie_list, mock_scanner, mock_loaders
|
||||
):
|
||||
"""Test SeriesApp initializes with database session."""
|
||||
test_dir = "/test/anime"
|
||||
mock_db = Mock()
|
||||
|
||||
# Create app with db_session
|
||||
app = SeriesApp(test_dir, db_session=mock_db)
|
||||
|
||||
# Verify db_session is set
|
||||
assert app._db_session is mock_db
|
||||
assert app.db_session is mock_db
|
||||
|
||||
# Verify SerieList was called with db_session
|
||||
call_kwargs = mock_serie_list.call_args[1]
|
||||
assert call_kwargs.get("db_session") is mock_db
|
||||
|
||||
# Verify SerieScanner was called with db_session
|
||||
call_kwargs = mock_scanner.call_args[1]
|
||||
assert call_kwargs.get("db_session") is mock_db
|
||||
|
||||
|
||||
class TestSeriesAppDatabaseSession:
|
||||
"""Test SeriesApp database session management."""
|
||||
|
||||
@patch('src.core.SeriesApp.Loaders')
|
||||
@patch('src.core.SeriesApp.SerieScanner')
|
||||
@patch('src.core.SeriesApp.SerieList')
|
||||
def test_set_db_session_updates_all_components(
|
||||
self, mock_serie_list, mock_scanner, mock_loaders
|
||||
):
|
||||
"""Test set_db_session updates app, list, and scanner."""
|
||||
test_dir = "/test/anime"
|
||||
mock_list = Mock()
|
||||
mock_list.GetMissingEpisode.return_value = []
|
||||
mock_scan = Mock()
|
||||
mock_serie_list.return_value = mock_list
|
||||
mock_scanner.return_value = mock_scan
|
||||
|
||||
# Create app without db_session
|
||||
app = SeriesApp(test_dir)
|
||||
assert app.db_session is None
|
||||
|
||||
# Create mock database session
|
||||
mock_db = Mock()
|
||||
|
||||
# Set database session
|
||||
app.set_db_session(mock_db)
|
||||
|
||||
# Verify all components are updated
|
||||
assert app._db_session is mock_db
|
||||
assert app.db_session is mock_db
|
||||
assert mock_list._db_session is mock_db
|
||||
assert mock_scan._db_session is mock_db
|
||||
|
||||
@patch('src.core.SeriesApp.Loaders')
|
||||
@patch('src.core.SeriesApp.SerieScanner')
|
||||
@patch('src.core.SeriesApp.SerieList')
|
||||
def test_set_db_session_to_none(
|
||||
self, mock_serie_list, mock_scanner, mock_loaders
|
||||
):
|
||||
"""Test setting db_session to None."""
|
||||
test_dir = "/test/anime"
|
||||
mock_list = Mock()
|
||||
mock_list.GetMissingEpisode.return_value = []
|
||||
mock_scan = Mock()
|
||||
mock_serie_list.return_value = mock_list
|
||||
mock_scanner.return_value = mock_scan
|
||||
mock_db = Mock()
|
||||
|
||||
# Create app with db_session
|
||||
app = SeriesApp(test_dir, db_session=mock_db)
|
||||
|
||||
# Set database session to None
|
||||
app.set_db_session(None)
|
||||
|
||||
# Verify all components are updated
|
||||
assert app._db_session is None
|
||||
assert app.db_session is None
|
||||
assert mock_list._db_session is None
|
||||
assert mock_scan._db_session is None
|
||||
|
||||
|
||||
class TestSeriesAppAsyncDbInit:
|
||||
"""Test SeriesApp async database initialization."""
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch('src.core.SeriesApp.Loaders')
|
||||
@patch('src.core.SeriesApp.SerieScanner')
|
||||
@patch('src.core.SeriesApp.SerieList')
|
||||
async def test_init_from_db_async_loads_from_database(
|
||||
self, mock_serie_list, mock_scanner, mock_loaders
|
||||
):
|
||||
"""Test init_from_db_async loads series from database."""
|
||||
import warnings
|
||||
|
||||
test_dir = "/test/anime"
|
||||
mock_list = Mock()
|
||||
mock_list.load_series_from_db = AsyncMock()
|
||||
mock_list.GetMissingEpisode.return_value = [{"name": "Test"}]
|
||||
mock_serie_list.return_value = mock_list
|
||||
mock_db = Mock()
|
||||
|
||||
# Create app with db_session
|
||||
app = SeriesApp(test_dir, db_session=mock_db)
|
||||
|
||||
# Initialize from database
|
||||
await app.init_from_db_async()
|
||||
|
||||
# Verify load_series_from_db was called
|
||||
mock_list.load_series_from_db.assert_called_once_with(mock_db)
|
||||
|
||||
# Verify series_list is populated
|
||||
assert len(app.series_list) == 1
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch('src.core.SeriesApp.Loaders')
|
||||
@patch('src.core.SeriesApp.SerieScanner')
|
||||
@patch('src.core.SeriesApp.SerieList')
|
||||
async def test_init_from_db_async_without_session_warns(
|
||||
self, mock_serie_list, mock_scanner, mock_loaders
|
||||
):
|
||||
"""Test init_from_db_async warns without db_session."""
|
||||
import warnings
|
||||
|
||||
test_dir = "/test/anime"
|
||||
mock_list = Mock()
|
||||
mock_list.GetMissingEpisode.return_value = []
|
||||
mock_serie_list.return_value = mock_list
|
||||
|
||||
# Create app without db_session
|
||||
app = SeriesApp(test_dir)
|
||||
|
||||
# Initialize from database should warn
|
||||
with warnings.catch_warnings(record=True) as w:
|
||||
warnings.simplefilter("always")
|
||||
await app.init_from_db_async()
|
||||
|
||||
# Check warning was raised
|
||||
assert len(w) == 1
|
||||
assert "without db_session" in str(w[0].message)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user