refactor: restructure core→server, split large entity files into database module

- Move src/core/ → src/server/
- Split SerieList.py (531 lines) and series.py (414 lines) into src/server/database/
- Add database/models.py for SQLAlchemy models
- Update all test imports to reflect new structure
- Remove deprecated test files (test_serie_class.py, test_serie_folder_with_year.py)
This commit is contained in:
2026-06-04 21:11:53 +02:00
parent 09d454d4c0
commit 5526ab884a
76 changed files with 1186 additions and 3574 deletions

View File

@@ -7,8 +7,8 @@ from unittest.mock import MagicMock, patch
import pytest
from src.core.entities.series import Serie
from src.core.SerieScanner import SerieScanner
from src.server.database.models import AnimeSeries
from src.server.SerieScanner import SerieScanner
@pytest.fixture
@@ -51,7 +51,7 @@ class TestGetSerieFromFolderDbLookup:
mock_anime_series.episodes = []
mock_session.execute.return_value.scalar_one_or_none.return_value = mock_anime_series
with patch("src.core.SerieScanner.get_sync_session", return_value=mock_session):
with patch("src.server.SerieScanner.get_sync_session", return_value=mock_session):
scanner = SerieScanner(temp_directory, mock_loader)
result = scanner._SerieScanner__read_data_from_file("Rooster Fighter (2026)")
@@ -60,48 +60,30 @@ class TestGetSerieFromFolderDbLookup:
assert result.name == "Rooster Fighter"
assert result.year == 2026
def test_db_miss_falls_back_to_provider_callback(self, temp_directory, mock_loader):
"""DB miss -> _db_lookup callback called."""
lookup = MagicMock(return_value=Serie(
key="rooster-fighter",
name="Rooster Fighter",
site="aniworld.to",
folder="Rooster Fighter (2026)",
episodeDict={},
))
scanner = SerieScanner(temp_directory, mock_loader, db_lookup=lookup)
def test_db_miss_returns_none(self, temp_directory, mock_loader):
"""DB miss -> returns None (no fallback)."""
mock_session = MagicMock()
mock_session.execute.return_value.scalar_one_or_none.return_value = None
result = scanner._SerieScanner__read_data_from_file("Rooster Fighter (2026)")
with patch("src.server.SerieScanner.get_sync_session", return_value=mock_session):
scanner = SerieScanner(temp_directory, mock_loader)
result = scanner._SerieScanner__read_data_from_file("Unknown Series (2026)")
assert result is not None
assert result.key == "rooster-fighter"
lookup.assert_called_once_with("Rooster Fighter (2026)")
def test_no_db_no_callback_generates_key_from_folder_name(self, temp_directory, mock_loader):
"""No DB entry, no callback -> key generated from folder name."""
folder = os.path.join(temp_directory, "Legacy Series")
os.makedirs(folder, exist_ok=True)
# No key file, no data file - should fall through to Step 4 (key generation)
scanner = SerieScanner(temp_directory, mock_loader)
result = scanner._SerieScanner__read_data_from_file("Legacy Series")
assert result is not None
assert result.key == "legacy-series"
assert result.folder == "Legacy Series"
assert result is None
def test_db_lookup_exception_caught_and_logged(self, temp_directory, mock_loader):
"""DB exception -> fallback to provider callback."""
def bad_lookup(folder):
raise RuntimeError("DB connection failed")
"""DB exception -> returns None without raising."""
with patch(
"src.server.SerieScanner.get_sync_session",
side_effect=RuntimeError("DB connection failed")
):
scanner = SerieScanner(temp_directory, mock_loader)
scanner = SerieScanner(temp_directory, mock_loader, db_lookup=bad_lookup)
with patch.object(logging.getLogger("src.core.SerieScanner"), "warning") as mock_warning:
result = scanner._SerieScanner__read_data_from_file("Rooster Fighter (2026)")
mock_warning.assert_called()
assert any("DB lookup failed" in str(c) for c in mock_warning.call_args_list)
with patch.object(logging.getLogger("src.server.SerieScanner"), "warning") as mock_warning:
result = scanner._SerieScanner__read_data_from_file("Rooster Fighter (2026)")
mock_warning.assert_called()
assert any("DB lookup failed" in str(c) for c in mock_warning.call_args_list)
assert result is None
class TestGetSerieFromFolderEdgeCases: