Files
Aniworld/tests/unit/test_serie_list.py
Lukas 5526ab884a 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)
2026-06-04 21:11:53 +02:00

181 lines
6.7 KiB
Python

"""Tests for SerieList class - DB-only operations."""
from unittest.mock import MagicMock
import pytest
from src.server.database.SerieList import SerieList
@pytest.fixture
def sample_serie():
"""Create a sample AnimeSeries mock for testing."""
anime = MagicMock()
anime.key = "attack-on-titan"
anime.name = "Attack on Titan"
anime.site = "https://aniworld.to/anime/stream/attack-on-titan"
anime.folder = "Attack on Titan (2013)"
anime.year = 2013
anime.nfo_path = None
anime.episodeDict = {1: [1, 2, 3]}
return anime
class TestSerieListKeyBasedStorage:
"""Test SerieList uses key for internal storage."""
def test_init_creates_empty_keydict(self, tmp_path):
"""Test initialization creates keyDict."""
serie_list = SerieList(str(tmp_path))
assert hasattr(serie_list, 'keyDict')
assert isinstance(serie_list.keyDict, dict)
assert len(serie_list.keyDict) == 0
def test_contains_checks_by_key(self, tmp_path, sample_serie):
"""Test contains() checks by key."""
serie_list = SerieList(str(tmp_path))
serie_list.keyDict[sample_serie.key] = sample_serie
assert serie_list.contains(sample_serie.key)
assert not serie_list.contains("nonexistent-key")
def test_get_by_key_returns_correct_serie(self, tmp_path, sample_serie):
"""Test get_by_key() retrieves series correctly."""
serie_list = SerieList(str(tmp_path))
serie_list.keyDict[sample_serie.key] = sample_serie
result = serie_list.get_by_key(sample_serie.key)
assert result is not None
assert result.key == sample_serie.key
assert result.name == sample_serie.name
def test_get_by_key_returns_none_for_missing(self, tmp_path):
"""Test get_by_key() returns None for nonexistent key."""
serie_list = SerieList(str(tmp_path))
result = serie_list.get_by_key("nonexistent-key")
assert result is None
def test_get_by_folder_backward_compatibility(self, tmp_path, sample_serie):
"""Test get_by_folder() provides backward compatibility."""
import warnings
serie_list = SerieList(str(tmp_path))
serie_list.keyDict[sample_serie.key] = sample_serie
with warnings.catch_warnings():
warnings.simplefilter("ignore", DeprecationWarning)
result = serie_list.get_by_folder(sample_serie.folder)
assert result is not None
assert result.key == sample_serie.key
assert result.folder == sample_serie.folder
def test_get_by_folder_returns_none_for_missing(self, tmp_path):
"""Test get_by_folder() returns None for nonexistent folder."""
import warnings
serie_list = SerieList(str(tmp_path))
with warnings.catch_warnings():
warnings.simplefilter("ignore", DeprecationWarning)
result = serie_list.get_by_folder("Nonexistent Folder")
assert result is None
def test_get_all_returns_all_series(self, tmp_path, sample_serie):
"""Test get_all() returns all series from keyDict."""
serie_list = SerieList(str(tmp_path))
serie2 = MagicMock()
serie2.key = "naruto"
serie2.name = "Naruto"
serie2.site = "https://aniworld.to/anime/stream/naruto"
serie2.folder = "Naruto (2002)"
serie2.episodeDict = {1: [1, 2]}
serie_list.keyDict[sample_serie.key] = sample_serie
serie_list.keyDict[serie2.key] = serie2
all_series = serie_list.get_all()
assert len(all_series) == 2
assert sample_serie in all_series
assert serie2 in all_series
def test_get_missing_episodes_filters_by_episode_dict(self, tmp_path):
"""Test get_missing_episodes() returns only series with episodes."""
serie_list = SerieList(str(tmp_path))
serie_with_episodes = MagicMock()
serie_with_episodes.key = "serie-with-episodes"
serie_with_episodes.name = "Serie With Episodes"
serie_with_episodes.episodeDict = {1: [1, 2, 3]}
serie_without_episodes = MagicMock()
serie_without_episodes.key = "serie-without-episodes"
serie_without_episodes.name = "Serie Without Episodes"
serie_without_episodes.episodeDict = {}
serie_list.keyDict[serie_with_episodes.key] = serie_with_episodes
serie_list.keyDict[serie_without_episodes.key] = serie_without_episodes
missing = serie_list.get_missing_episodes()
assert len(missing) == 1
assert serie_with_episodes in missing
assert serie_without_episodes not in missing
class TestSerieListPublicAPI:
"""Test that public API still works correctly."""
def test_public_methods_work(self, tmp_path, sample_serie):
"""Test that all public methods work correctly after refactoring."""
serie_list = SerieList(str(tmp_path))
# Add directly to keyDict (simulating DB load)
serie_list.keyDict[sample_serie.key] = sample_serie
# Test contains
assert serie_list.contains(sample_serie.key)
# Test GetList/get_all
assert len(serie_list.GetList()) == 1
assert len(serie_list.get_all()) == 1
# Test GetMissingEpisode/get_missing_episodes
assert len(serie_list.GetMissingEpisode()) == 1
assert len(serie_list.get_missing_episodes()) == 1
# Test get_by_key
assert serie_list.get_by_key(sample_serie.key) is not None
class TestSerieListDeprecationWarnings:
"""Test deprecation warnings are raised for deprecated methods."""
def test_get_by_folder_raises_deprecation_warning(self, tmp_path, sample_serie):
"""Test get_by_folder() raises deprecation warning."""
import warnings
serie_list = SerieList(str(tmp_path))
serie_list.keyDict[sample_serie.key] = sample_serie
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter("always")
serie_list.get_by_folder(sample_serie.folder)
# Check deprecation warning was raised
assert len(w) == 1
assert issubclass(w[0].category, DeprecationWarning)
assert "get_by_key()" in str(w[0].message)
class TestInvalidateCache:
"""Test invalidate_cache method."""
def test_invalidate_cache_clears_keydict(self, tmp_path, sample_serie):
"""Verify invalidate_cache clears the in-memory cache."""
serie_list = SerieList(str(tmp_path))
serie_list.keyDict[sample_serie.key] = sample_serie
assert len(serie_list.keyDict) == 1
serie_list.invalidate_cache()
assert len(serie_list.keyDict) == 0