refactor: remove database access from core layer
- Remove db_session parameter from SeriesApp, SerieList, SerieScanner - Move all database operations to AnimeService (service layer) - Add add_series_to_db, contains_in_db methods to AnimeService - Update sync_series_from_data_files to use inline DB operations - Remove obsolete test classes for removed DB methods - Fix pylint issues: add broad-except comments, fix line lengths - Core layer (src/core/) now has zero database imports 722 unit tests pass
This commit is contained in:
@@ -251,9 +251,10 @@ class TestSeriesAppReScan:
|
||||
app.serie_scanner.get_total_to_scan = Mock(return_value=5)
|
||||
app.serie_scanner.reinit = Mock()
|
||||
app.serie_scanner.scan = Mock()
|
||||
app.serie_scanner.keyDict = {}
|
||||
|
||||
# Perform rescan with file-based mode (use_database=False)
|
||||
await app.rescan(use_database=False)
|
||||
# Perform rescan
|
||||
await app.rescan()
|
||||
|
||||
# Verify rescan completed
|
||||
app.serie_scanner.reinit.assert_called_once()
|
||||
@@ -266,7 +267,7 @@ class TestSeriesAppReScan:
|
||||
async def test_rescan_with_callback(
|
||||
self, mock_serie_list, mock_scanner, mock_loaders
|
||||
):
|
||||
"""Test rescan with progress callbacks (file-based mode)."""
|
||||
"""Test rescan with progress callbacks."""
|
||||
test_dir = "/test/anime"
|
||||
app = SeriesApp(test_dir)
|
||||
|
||||
@@ -276,6 +277,7 @@ class TestSeriesAppReScan:
|
||||
# Mock scanner
|
||||
app.serie_scanner.get_total_to_scan = Mock(return_value=3)
|
||||
app.serie_scanner.reinit = Mock()
|
||||
app.serie_scanner.keyDict = {}
|
||||
|
||||
def mock_scan(callback):
|
||||
callback("folder1", 1)
|
||||
@@ -284,8 +286,8 @@ class TestSeriesAppReScan:
|
||||
|
||||
app.serie_scanner.scan = Mock(side_effect=mock_scan)
|
||||
|
||||
# Perform rescan with file-based mode (use_database=False)
|
||||
await app.rescan(use_database=False)
|
||||
# Perform rescan
|
||||
await app.rescan()
|
||||
|
||||
# Verify rescan completed
|
||||
app.serie_scanner.scan.assert_called_once()
|
||||
@@ -297,7 +299,7 @@ class TestSeriesAppReScan:
|
||||
async def test_rescan_cancellation(
|
||||
self, mock_serie_list, mock_scanner, mock_loaders
|
||||
):
|
||||
"""Test rescan cancellation (file-based mode)."""
|
||||
"""Test rescan cancellation."""
|
||||
test_dir = "/test/anime"
|
||||
app = SeriesApp(test_dir)
|
||||
|
||||
@@ -313,9 +315,9 @@ class TestSeriesAppReScan:
|
||||
|
||||
app.serie_scanner.scan = Mock(side_effect=mock_scan)
|
||||
|
||||
# Perform rescan - should handle cancellation (file-based mode)
|
||||
# Perform rescan - should handle cancellation
|
||||
try:
|
||||
await app.rescan(use_database=False)
|
||||
await app.rescan()
|
||||
except Exception:
|
||||
pass # Cancellation is expected
|
||||
|
||||
@@ -386,178 +388,72 @@ class TestSeriesAppGetters:
|
||||
|
||||
|
||||
class TestSeriesAppDatabaseInit:
|
||||
"""Test SeriesApp database initialization."""
|
||||
"""Test SeriesApp initialization (no database support in core)."""
|
||||
|
||||
@patch('src.core.SeriesApp.Loaders')
|
||||
@patch('src.core.SeriesApp.SerieScanner')
|
||||
@patch('src.core.SeriesApp.SerieList')
|
||||
def test_init_without_db_session(
|
||||
def test_init_creates_components(
|
||||
self, mock_serie_list, mock_scanner, mock_loaders
|
||||
):
|
||||
"""Test SeriesApp initializes without database session."""
|
||||
"""Test SeriesApp initializes all components."""
|
||||
test_dir = "/test/anime"
|
||||
|
||||
# Create app without db_session
|
||||
# Create app
|
||||
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
|
||||
# Verify SerieList was called
|
||||
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
|
||||
# Verify SerieScanner was called
|
||||
mock_scanner.assert_called_once()
|
||||
|
||||
|
||||
class TestSeriesAppLoadSeriesFromList:
|
||||
"""Test SeriesApp load_series_from_list method."""
|
||||
|
||||
@patch('src.core.SeriesApp.Loaders')
|
||||
@patch('src.core.SeriesApp.SerieScanner')
|
||||
@patch('src.core.SeriesApp.SerieList')
|
||||
def test_init_with_db_session(
|
||||
def test_load_series_from_list_populates_keydict(
|
||||
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 load_series_from_list populates the list correctly."""
|
||||
from src.core.entities.series import Serie
|
||||
|
||||
test_dir = "/test/anime"
|
||||
mock_list = Mock()
|
||||
mock_list.GetMissingEpisode.return_value = []
|
||||
mock_list.keyDict = {}
|
||||
mock_serie_list.return_value = mock_list
|
||||
|
||||
# Create app without db_session
|
||||
# Create app
|
||||
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)
|
||||
# Create test series
|
||||
test_series = [
|
||||
Serie(
|
||||
key="anime1",
|
||||
name="Anime 1",
|
||||
site="aniworld.to",
|
||||
folder="Anime 1",
|
||||
episodeDict={1: [1, 2]}
|
||||
),
|
||||
Serie(
|
||||
key="anime2",
|
||||
name="Anime 2",
|
||||
site="aniworld.to",
|
||||
folder="Anime 2",
|
||||
episodeDict={1: [1]}
|
||||
),
|
||||
]
|
||||
|
||||
# Load series
|
||||
app.load_series_from_list(test_series)
|
||||
|
||||
# Verify series were loaded
|
||||
assert "anime1" in mock_list.keyDict
|
||||
assert "anime2" in mock_list.keyDict
|
||||
|
||||
|
||||
class TestSeriesAppGetAllSeriesFromDataFiles:
|
||||
|
||||
Reference in New Issue
Block a user