""" 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)"