Complete Phase 7: Testing and Validation for identifier standardization

- Task 7.1: Update All Test Fixtures to Use Key
  - Updated FakeSerie/FakeSeriesApp with realistic keys in test_anime_endpoints.py
  - Updated 6+ fixtures in test_websocket_integration.py
  - Updated 5 fixtures in test_download_progress_integration.py
  - Updated 9 fixtures in test_download_progress_websocket.py
  - Updated 10+ fixtures in test_download_models.py
  - All fixtures now use URL-safe, lowercase, hyphenated key format

- Task 7.2: Add Integration Tests for Identifier Consistency
  - Created tests/integration/test_identifier_consistency.py with 10 tests
  - TestAPIIdentifierConsistency: API response validation
  - TestServiceIdentifierConsistency: Download service key usage
  - TestWebSocketIdentifierConsistency: WebSocket events
  - TestIdentifierValidation: Model validation
  - TestEndToEndIdentifierFlow: Full flow verification
  - Tests use UUID suffixes for isolation

All 1006 tests passing.
This commit is contained in:
2025-11-28 17:41:54 +01:00
parent 0c8b296aa6
commit 6e9087d0f4
7 changed files with 680 additions and 87 deletions

View File

@@ -10,10 +10,25 @@ from src.server.services.auth_service import auth_service
class FakeSerie:
"""Mock Serie object for testing."""
"""Mock Serie object for testing.
Note on identifiers:
- key: Provider-assigned URL-safe identifier (e.g., 'attack-on-titan')
- folder: Filesystem folder name for metadata only (e.g., 'Attack on Titan (2013)')
The 'key' is the primary identifier used for all lookups and operations.
The 'folder' is metadata only, not used for identification.
"""
def __init__(self, key, name, folder, episodeDict=None):
"""Initialize fake serie."""
"""Initialize fake serie.
Args:
key: Provider-assigned URL-safe key (primary identifier)
name: Display name for the series
folder: Filesystem folder name (metadata only)
episodeDict: Dictionary of missing episodes
"""
self.key = key
self.name = name
self.folder = folder
@@ -28,8 +43,9 @@ class FakeSeriesApp:
"""Initialize fake series app."""
self.list = self # Changed from self.List to self.list
self._items = [
FakeSerie("1", "Test Show", "test_show", {1: [1, 2]}),
FakeSerie("2", "Complete Show", "complete_show", {}),
# Using realistic key values (URL-safe, lowercase, hyphenated)
FakeSerie("test-show-key", "Test Show", "Test Show (2023)", {1: [1, 2]}),
FakeSerie("complete-show-key", "Complete Show", "Complete Show (2022)", {}),
]
def GetMissingEpisode(self):
@@ -120,9 +136,15 @@ def test_list_anime_direct_call():
def test_get_anime_detail_direct_call():
"""Test get_anime function directly."""
"""Test get_anime function directly.
Uses the series key (test-show-key) for lookup, not the folder name.
"""
fake = FakeSeriesApp()
result = asyncio.run(anime_module.get_anime("1", series_app=fake))
# Use the series key (primary identifier) for lookup
result = asyncio.run(
anime_module.get_anime("test-show-key", series_app=fake)
)
assert result.title == "Test Show"
assert "1-1" in result.episodes