Aniworld/tests/unit/test_template_helpers.py
Lukas 5934c7666c Task 4.7: Update template helpers to use key identifier
- Add series context helpers: prepare_series_context, get_series_by_key, filter_series_by_missing_episodes
- Update module docstring with identifier convention documentation
- Add unit tests for new series context helper functions
- Update infrastructure.md with template helpers documentation
- Mark Phase 4 (API Layer) as complete
2025-11-28 16:00:15 +01:00

244 lines
8.1 KiB
Python

"""
Tests for template helper utilities.
This module tests the template helper functions including series context
preparation using `key` as the primary identifier.
"""
from unittest.mock import Mock
import pytest
from src.server.utils.template_helpers import (
filter_series_by_missing_episodes,
get_base_context,
get_series_by_key,
list_available_templates,
prepare_series_context,
validate_template_exists,
)
class TestTemplateHelpers:
"""Test template helper utilities."""
def test_get_base_context(self):
"""Test that base context is created correctly."""
request = Mock()
context = get_base_context(request, "Test Title")
assert "request" in context
assert context["request"] == request
assert context["title"] == "Test Title"
assert context["app_name"] == "Aniworld Download Manager"
assert context["version"] == "1.0.0"
def test_get_base_context_default_title(self):
"""Test that default title is used."""
request = Mock()
context = get_base_context(request)
assert context["title"] == "Aniworld"
def test_validate_template_exists_true(self):
"""Test template validation for existing template."""
# index.html should exist
exists = validate_template_exists("index.html")
assert exists is True
def test_validate_template_exists_false(self):
"""Test template validation for non-existing template."""
exists = validate_template_exists("nonexistent.html")
assert exists is False
def test_list_available_templates(self):
"""Test listing available templates."""
templates = list_available_templates()
# Should be a list
assert isinstance(templates, list)
# Should contain at least the main templates
expected_templates = [
"index.html",
"login.html",
"setup.html",
"queue.html",
"error.html"
]
for expected in expected_templates:
assert expected in templates, (
f"{expected} not found in templates list"
)
def test_list_available_templates_only_html(self):
"""Test that only HTML files are listed."""
templates = list_available_templates()
for template in templates:
assert template.endswith(".html")
@pytest.mark.parametrize("template_name", [
"index.html",
"login.html",
"setup.html",
"queue.html",
"error.html"
])
def test_all_required_templates_exist(self, template_name):
"""Test that all required templates exist."""
assert validate_template_exists(template_name), \
f"Required template {template_name} does not exist"
class TestSeriesContextHelpers:
"""Test series context helper functions.
These tests verify that series helpers use `key` as the primary
identifier following the project's identifier convention.
"""
def test_prepare_series_context_uses_key(self):
"""Test that prepare_series_context uses key as primary identifier."""
series_data = [
{
"key": "attack-on-titan",
"name": "Attack on Titan",
"folder": "Attack on Titan (2013)",
},
{
"key": "one-piece",
"name": "One Piece",
"folder": "One Piece (1999)",
},
]
prepared = prepare_series_context(series_data)
assert len(prepared) == 2
# Verify key is present and used
assert prepared[0]["key"] in ("attack-on-titan", "one-piece")
assert all("key" in item for item in prepared)
assert all("folder" in item for item in prepared)
def test_prepare_series_context_sorts_by_name(self):
"""Test that series are sorted by name by default."""
series_data = [
{"key": "z-series", "name": "Zebra Anime", "folder": "z"},
{"key": "a-series", "name": "Alpha Anime", "folder": "a"},
]
prepared = prepare_series_context(series_data, sort_by="name")
assert prepared[0]["name"] == "Alpha Anime"
assert prepared[1]["name"] == "Zebra Anime"
def test_prepare_series_context_sorts_by_key(self):
"""Test that series can be sorted by key."""
series_data = [
{"key": "z-series", "name": "Zebra", "folder": "z"},
{"key": "a-series", "name": "Alpha", "folder": "a"},
]
prepared = prepare_series_context(series_data, sort_by="key")
assert prepared[0]["key"] == "a-series"
assert prepared[1]["key"] == "z-series"
def test_prepare_series_context_empty_list(self):
"""Test prepare_series_context with empty list."""
prepared = prepare_series_context([])
assert prepared == []
def test_prepare_series_context_skips_missing_key(self):
"""Test that items without key are skipped with warning."""
series_data = [
{"key": "valid-series", "name": "Valid", "folder": "valid"},
{"name": "No Key", "folder": "nokey"}, # Missing key
]
prepared = prepare_series_context(series_data)
assert len(prepared) == 1
assert prepared[0]["key"] == "valid-series"
def test_prepare_series_context_preserves_extra_fields(self):
"""Test that extra fields are preserved."""
series_data = [
{
"key": "test",
"name": "Test",
"folder": "test",
"missing_episodes": {"1": [1, 2]},
"site": "aniworld.to",
}
]
prepared = prepare_series_context(series_data)
assert prepared[0]["missing_episodes"] == {"1": [1, 2]}
assert prepared[0]["site"] == "aniworld.to"
def test_get_series_by_key_found(self):
"""Test finding a series by key."""
series_data = [
{"key": "attack-on-titan", "name": "Attack on Titan"},
{"key": "one-piece", "name": "One Piece"},
]
result = get_series_by_key(series_data, "attack-on-titan")
assert result is not None
assert result["name"] == "Attack on Titan"
def test_get_series_by_key_not_found(self):
"""Test that None is returned when key not found."""
series_data = [
{"key": "attack-on-titan", "name": "Attack on Titan"},
]
result = get_series_by_key(series_data, "non-existent")
assert result is None
def test_get_series_by_key_empty_list(self):
"""Test get_series_by_key with empty list."""
result = get_series_by_key([], "any-key")
assert result is None
def test_filter_series_by_missing_episodes(self):
"""Test filtering series with missing episodes."""
series_data = [
{
"key": "has-missing",
"name": "Has Missing",
"missing_episodes": {"1": [1, 2, 3]},
},
{
"key": "no-missing",
"name": "No Missing",
"missing_episodes": {},
},
{
"key": "empty-seasons",
"name": "Empty Seasons",
"missing_episodes": {"1": [], "2": []},
},
]
filtered = filter_series_by_missing_episodes(series_data)
assert len(filtered) == 1
assert filtered[0]["key"] == "has-missing"
def test_filter_series_by_missing_episodes_empty(self):
"""Test filter with empty list."""
filtered = filter_series_by_missing_episodes([])
assert filtered == []
def test_filter_preserves_key_identifier(self):
"""Test that filter preserves key as identifier."""
series_data = [
{
"key": "test-series",
"folder": "Test Series (2020)",
"name": "Test",
"missing_episodes": {"1": [1]},
}
]
filtered = filter_series_by_missing_episodes(series_data)
assert filtered[0]["key"] == "test-series"
assert filtered[0]["folder"] == "Test Series (2020)"