Aniworld/tests/unit/test_serie_list.py
Lukas 8b5b06ca9a feat: Standardize SerieList to use key as primary identifier (Task 1.2)
- Renamed folderDict to keyDict for clarity
- Updated internal storage to use serie.key instead of serie.folder
- Optimized contains() from O(n) to O(1) with direct key lookup
- Added get_by_key() as primary lookup method
- Added get_by_folder() for backward compatibility
- Enhanced docstrings to clarify key vs folder usage
- Created comprehensive test suite (12 tests, all passing)
- Verified no breaking changes (16 SeriesApp tests pass)

This establishes key as the single source of truth for series
identification while maintaining folder as metadata for filesystem
operations only.
2025-11-23 12:25:08 +01:00

204 lines
7.1 KiB
Python

"""Tests for SerieList class - identifier standardization."""
import os
import tempfile
import pytest
from src.core.entities.SerieList import SerieList
from src.core.entities.series import Serie
@pytest.fixture
def temp_directory():
"""Create a temporary directory for testing."""
with tempfile.TemporaryDirectory() as tmpdir:
yield tmpdir
@pytest.fixture
def sample_serie():
"""Create a sample Serie for testing."""
return Serie(
key="attack-on-titan",
name="Attack on Titan",
site="https://aniworld.to/anime/stream/attack-on-titan",
folder="Attack on Titan (2013)",
episodeDict={1: [1, 2, 3]}
)
class TestSerieListKeyBasedStorage:
"""Test SerieList uses key for internal storage."""
def test_init_creates_empty_keydict(self, temp_directory):
"""Test initialization creates keyDict."""
serie_list = SerieList(temp_directory)
assert hasattr(serie_list, 'keyDict')
assert isinstance(serie_list.keyDict, dict)
def test_add_stores_by_key(self, temp_directory, sample_serie):
"""Test add() stores series by key."""
serie_list = SerieList(temp_directory)
serie_list.add(sample_serie)
# Verify stored by key, not folder
assert sample_serie.key in serie_list.keyDict
assert serie_list.keyDict[sample_serie.key] == sample_serie
def test_contains_checks_by_key(self, temp_directory, sample_serie):
"""Test contains() checks by key."""
serie_list = SerieList(temp_directory)
serie_list.add(sample_serie)
assert serie_list.contains(sample_serie.key)
assert not serie_list.contains("nonexistent-key")
def test_add_prevents_duplicates_by_key(
self, temp_directory, sample_serie
):
"""Test add() prevents duplicates based on key."""
serie_list = SerieList(temp_directory)
# Add same serie twice
serie_list.add(sample_serie)
initial_count = len(serie_list.keyDict)
serie_list.add(sample_serie)
# Should still have only one entry
assert len(serie_list.keyDict) == initial_count
assert len(serie_list.keyDict) == 1
def test_get_by_key_returns_correct_serie(
self, temp_directory, sample_serie
):
"""Test get_by_key() retrieves series correctly."""
serie_list = SerieList(temp_directory)
serie_list.add(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, temp_directory):
"""Test get_by_key() returns None for nonexistent key."""
serie_list = SerieList(temp_directory)
result = serie_list.get_by_key("nonexistent-key")
assert result is None
def test_get_by_folder_backward_compatibility(
self, temp_directory, sample_serie
):
"""Test get_by_folder() provides backward compatibility."""
serie_list = SerieList(temp_directory)
serie_list.add(sample_serie)
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, temp_directory):
"""Test get_by_folder() returns None for nonexistent folder."""
serie_list = SerieList(temp_directory)
result = serie_list.get_by_folder("Nonexistent Folder")
assert result is None
def test_get_all_returns_all_series(self, temp_directory, sample_serie):
"""Test get_all() returns all series from keyDict."""
serie_list = SerieList(temp_directory)
serie_list.add(sample_serie)
serie2 = Serie(
key="naruto",
name="Naruto",
site="https://aniworld.to/anime/stream/naruto",
folder="Naruto (2002)",
episodeDict={1: [1, 2]}
)
serie_list.add(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, temp_directory
):
"""Test get_missing_episodes() returns only series with episodes."""
serie_list = SerieList(temp_directory)
# Serie with missing episodes
serie_with_episodes = Serie(
key="serie-with-episodes",
name="Serie With Episodes",
site="https://aniworld.to/anime/stream/serie-with-episodes",
folder="Serie With Episodes (2020)",
episodeDict={1: [1, 2, 3]}
)
# Serie without missing episodes
serie_without_episodes = Serie(
key="serie-without-episodes",
name="Serie Without Episodes",
site="https://aniworld.to/anime/stream/serie-without-episodes",
folder="Serie Without Episodes (2021)",
episodeDict={}
)
serie_list.add(serie_with_episodes)
serie_list.add(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
def test_load_series_stores_by_key(self, temp_directory, sample_serie):
"""Test load_series() stores series by key when loading from disk."""
# Create directory structure and save serie
folder_path = os.path.join(temp_directory, sample_serie.folder)
os.makedirs(folder_path, exist_ok=True)
data_path = os.path.join(folder_path, "data")
sample_serie.save_to_file(data_path)
# Create new SerieList (triggers load_series in __init__)
serie_list = SerieList(temp_directory)
# Verify loaded by key
assert sample_serie.key in serie_list.keyDict
loaded_serie = serie_list.keyDict[sample_serie.key]
assert loaded_serie.key == sample_serie.key
assert loaded_serie.name == sample_serie.name
class TestSerieListPublicAPI:
"""Test that public API still works correctly."""
def test_public_methods_work(self, temp_directory, sample_serie):
"""Test that all public methods work correctly after refactoring."""
serie_list = SerieList(temp_directory)
# Test add
serie_list.add(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 new helper methods
assert serie_list.get_by_key(sample_serie.key) is not None
assert serie_list.get_by_folder(sample_serie.folder) is not None