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:
@@ -171,9 +171,10 @@ class TestDownloadItem:
|
||||
def test_valid_download_item(self):
|
||||
"""Test creating a valid download item."""
|
||||
episode = EpisodeIdentifier(season=1, episode=5)
|
||||
# Note: serie_id uses provider key format (URL-safe, lowercase)
|
||||
item = DownloadItem(
|
||||
id="download_123",
|
||||
serie_id="serie_456",
|
||||
serie_id="test-serie-key",
|
||||
serie_folder="Test Series (2023)",
|
||||
serie_name="Test Series",
|
||||
episode=episode,
|
||||
@@ -181,7 +182,7 @@ class TestDownloadItem:
|
||||
priority=DownloadPriority.HIGH
|
||||
)
|
||||
assert item.id == "download_123"
|
||||
assert item.serie_id == "serie_456"
|
||||
assert item.serie_id == "test-serie-key"
|
||||
assert item.serie_name == "Test Series"
|
||||
assert item.episode == episode
|
||||
assert item.status == DownloadStatus.PENDING
|
||||
@@ -214,10 +215,11 @@ class TestDownloadItem:
|
||||
def test_download_item_defaults(self):
|
||||
"""Test default values for download item."""
|
||||
episode = EpisodeIdentifier(season=1, episode=1)
|
||||
# Note: serie_id uses provider key format (URL-safe, lowercase)
|
||||
item = DownloadItem(
|
||||
id="test_id",
|
||||
serie_id="serie_id",
|
||||
serie_folder="Test Folder",
|
||||
serie_id="default-test-key",
|
||||
serie_folder="Test Folder (2024)",
|
||||
serie_name="Test",
|
||||
episode=episode
|
||||
)
|
||||
@@ -234,10 +236,11 @@ class TestDownloadItem:
|
||||
"""Test download item with progress information."""
|
||||
episode = EpisodeIdentifier(season=1, episode=1)
|
||||
progress = DownloadProgress(percent=50.0, downloaded_mb=100.0)
|
||||
# Note: serie_id uses provider key format (URL-safe, lowercase)
|
||||
item = DownloadItem(
|
||||
id="test_id",
|
||||
serie_id="serie_id",
|
||||
serie_folder="Test Folder",
|
||||
serie_id="progress-test-key",
|
||||
serie_folder="Test Folder (2024)",
|
||||
serie_name="Test",
|
||||
episode=episode,
|
||||
progress=progress
|
||||
@@ -249,10 +252,11 @@ class TestDownloadItem:
|
||||
"""Test download item with timestamp fields."""
|
||||
episode = EpisodeIdentifier(season=1, episode=1)
|
||||
now = datetime.now(timezone.utc)
|
||||
# Note: serie_id uses provider key format (URL-safe, lowercase)
|
||||
item = DownloadItem(
|
||||
id="test_id",
|
||||
serie_id="serie_id",
|
||||
serie_folder="Test Folder",
|
||||
serie_id="timestamp-test-key",
|
||||
serie_folder="Test Folder (2024)",
|
||||
serie_name="Test",
|
||||
episode=episode,
|
||||
started_at=now,
|
||||
@@ -267,8 +271,8 @@ class TestDownloadItem:
|
||||
with pytest.raises(ValidationError):
|
||||
DownloadItem(
|
||||
id="test_id",
|
||||
serie_id="serie_id",
|
||||
serie_folder="Test Folder",
|
||||
serie_id="empty-name-test-key",
|
||||
serie_folder="Test Folder (2024)",
|
||||
serie_name="",
|
||||
episode=episode
|
||||
)
|
||||
@@ -279,8 +283,8 @@ class TestDownloadItem:
|
||||
with pytest.raises(ValidationError):
|
||||
DownloadItem(
|
||||
id="test_id",
|
||||
serie_id="serie_id",
|
||||
serie_folder="Test Folder",
|
||||
serie_id="retry-test-key",
|
||||
serie_folder="Test Folder (2024)",
|
||||
serie_name="Test",
|
||||
episode=episode,
|
||||
retry_count=-1
|
||||
@@ -290,10 +294,11 @@ class TestDownloadItem:
|
||||
"""Test that added_at is automatically set."""
|
||||
episode = EpisodeIdentifier(season=1, episode=1)
|
||||
before = datetime.now(timezone.utc)
|
||||
# Note: serie_id uses provider key format (URL-safe, lowercase)
|
||||
item = DownloadItem(
|
||||
id="test_id",
|
||||
serie_id="serie_id",
|
||||
serie_folder="Test Folder",
|
||||
serie_id="auto-added-test-key",
|
||||
serie_folder="Test Folder (2024)",
|
||||
serie_name="Test",
|
||||
episode=episode
|
||||
)
|
||||
@@ -307,10 +312,11 @@ class TestQueueStatus:
|
||||
def test_valid_queue_status(self):
|
||||
"""Test creating valid queue status."""
|
||||
episode = EpisodeIdentifier(season=1, episode=1)
|
||||
# Note: serie_id uses provider key format (URL-safe, lowercase)
|
||||
item = DownloadItem(
|
||||
id="test_id",
|
||||
serie_id="serie_id",
|
||||
serie_folder="Test Folder",
|
||||
serie_id="queue-status-test-key",
|
||||
serie_folder="Test Folder (2024)",
|
||||
serie_name="Test",
|
||||
episode=episode
|
||||
)
|
||||
@@ -405,14 +411,15 @@ class TestDownloadRequest:
|
||||
"""Test creating a valid download request."""
|
||||
episode1 = EpisodeIdentifier(season=1, episode=1)
|
||||
episode2 = EpisodeIdentifier(season=1, episode=2)
|
||||
# Note: serie_id uses provider key format (URL-safe, lowercase)
|
||||
request = DownloadRequest(
|
||||
serie_id="serie_123",
|
||||
serie_id="test-series-key",
|
||||
serie_folder="Test Series (2023)",
|
||||
serie_name="Test Series",
|
||||
episodes=[episode1, episode2],
|
||||
priority=DownloadPriority.HIGH
|
||||
)
|
||||
assert request.serie_id == "serie_123"
|
||||
assert request.serie_id == "test-series-key"
|
||||
assert request.serie_name == "Test Series"
|
||||
assert len(request.episodes) == 2
|
||||
assert request.priority == DownloadPriority.HIGH
|
||||
@@ -442,8 +449,9 @@ class TestDownloadRequest:
|
||||
def test_download_request_default_priority(self):
|
||||
"""Test default priority for download request."""
|
||||
episode = EpisodeIdentifier(season=1, episode=1)
|
||||
# Note: serie_id uses provider key format (URL-safe, lowercase)
|
||||
request = DownloadRequest(
|
||||
serie_id="serie_123",
|
||||
serie_id="default-priority-test-key",
|
||||
serie_folder="Test Series (2023)",
|
||||
serie_name="Test Series",
|
||||
episodes=[episode]
|
||||
@@ -456,8 +464,9 @@ class TestDownloadRequest:
|
||||
(endpoint validates)
|
||||
"""
|
||||
# Empty list is now allowed at model level; endpoint validates
|
||||
# Note: serie_id uses provider key format (URL-safe, lowercase)
|
||||
request = DownloadRequest(
|
||||
serie_id="serie_123",
|
||||
serie_id="empty-episodes-test-key",
|
||||
serie_folder="Test Series (2023)",
|
||||
serie_name="Test Series",
|
||||
episodes=[]
|
||||
@@ -468,8 +477,9 @@ class TestDownloadRequest:
|
||||
"""Test that empty serie name is rejected."""
|
||||
episode = EpisodeIdentifier(season=1, episode=1)
|
||||
with pytest.raises(ValidationError):
|
||||
# Note: serie_id uses provider key format (URL-safe, lowercase)
|
||||
DownloadRequest(
|
||||
serie_id="serie_123",
|
||||
serie_id="empty-name-request-key",
|
||||
serie_folder="Test Series (2023)",
|
||||
serie_name="",
|
||||
episodes=[episode]
|
||||
@@ -573,24 +583,27 @@ class TestModelSerialization:
|
||||
def test_download_item_to_dict(self):
|
||||
"""Test serializing download item to dict."""
|
||||
episode = EpisodeIdentifier(season=1, episode=5, title="Test")
|
||||
# Note: serie_id uses provider key format (URL-safe, lowercase)
|
||||
item = DownloadItem(
|
||||
id="test_id",
|
||||
serie_id="serie_id",
|
||||
serie_id="serialization-test-key",
|
||||
serie_folder="Test Series (2023)",
|
||||
serie_name="Test Series",
|
||||
episode=episode
|
||||
)
|
||||
data = item.model_dump()
|
||||
assert data["id"] == "test_id"
|
||||
assert data["serie_id"] == "serialization-test-key"
|
||||
assert data["serie_name"] == "Test Series"
|
||||
assert data["episode"]["season"] == 1
|
||||
assert data["episode"]["episode"] == 5
|
||||
|
||||
def test_download_item_from_dict(self):
|
||||
"""Test deserializing download item from dict."""
|
||||
# Note: serie_id uses provider key format (URL-safe, lowercase)
|
||||
data = {
|
||||
"id": "test_id",
|
||||
"serie_id": "serie_id",
|
||||
"serie_id": "deserialize-test-key",
|
||||
"serie_folder": "Test Series (2023)",
|
||||
"serie_name": "Test Series",
|
||||
"episode": {
|
||||
@@ -601,6 +614,7 @@ class TestModelSerialization:
|
||||
}
|
||||
item = DownloadItem(**data)
|
||||
assert item.id == "test_id"
|
||||
assert item.serie_id == "deserialize-test-key"
|
||||
assert item.serie_name == "Test Series"
|
||||
assert item.episode.season == 1
|
||||
|
||||
|
||||
@@ -147,9 +147,10 @@ class TestDownloadProgressWebSocket:
|
||||
progress_svc.subscribe("progress_updated", mock_event_handler)
|
||||
|
||||
# Add item to queue
|
||||
# Note: serie_id uses provider key format (URL-safe, lowercase)
|
||||
item_ids = await download_svc.add_to_queue(
|
||||
serie_id="test_serie_1",
|
||||
serie_folder="test_serie_1",
|
||||
serie_id="test-serie-1-key",
|
||||
serie_folder="Test Anime (2024)",
|
||||
serie_name="Test Anime",
|
||||
episodes=[EpisodeIdentifier(season=1, episode=1)],
|
||||
priority=DownloadPriority.NORMAL,
|
||||
@@ -197,9 +198,10 @@ class TestDownloadProgressWebSocket:
|
||||
progress_svc.subscribe("progress_updated", mock_event_handler)
|
||||
|
||||
# Add item with specific episode info
|
||||
# Note: serie_id uses provider key format (URL-safe, lowercase)
|
||||
await download_svc.add_to_queue(
|
||||
serie_id="test_serie_2",
|
||||
serie_folder="test_serie_2",
|
||||
serie_id="test-serie-2-key",
|
||||
serie_folder="My Test Anime (2024)",
|
||||
serie_name="My Test Anime",
|
||||
episodes=[EpisodeIdentifier(season=2, episode=5)],
|
||||
priority=DownloadPriority.HIGH,
|
||||
@@ -219,8 +221,9 @@ class TestDownloadProgressWebSocket:
|
||||
# Verify progress info is included
|
||||
data = progress_broadcasts[0]["data"]
|
||||
assert "id" in data
|
||||
# ID should contain folder name: download_test_serie_2_2_5
|
||||
assert "test_serie_2" in data["id"]
|
||||
# ID contains folder name: download_My Test Anime (2024)_2_5
|
||||
# Check for folder name substring (case-insensitive)
|
||||
assert "my test anime" in data["id"].lower()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_progress_percent_increases(self, download_service):
|
||||
@@ -236,9 +239,10 @@ class TestDownloadProgressWebSocket:
|
||||
|
||||
progress_svc.subscribe("progress_updated", mock_event_handler)
|
||||
|
||||
# Note: serie_id uses provider key format (URL-safe, lowercase)
|
||||
await download_svc.add_to_queue(
|
||||
serie_id="test_serie_3",
|
||||
serie_folder="test_serie_3",
|
||||
serie_id="test-serie-3-key",
|
||||
serie_folder="Progress Test (2024)",
|
||||
serie_name="Progress Test",
|
||||
episodes=[EpisodeIdentifier(season=1, episode=1)],
|
||||
)
|
||||
@@ -277,9 +281,10 @@ class TestDownloadProgressWebSocket:
|
||||
|
||||
progress_svc.subscribe("progress_updated", mock_event_handler)
|
||||
|
||||
# Note: serie_id uses provider key format (URL-safe, lowercase)
|
||||
await download_svc.add_to_queue(
|
||||
serie_id="test_serie_4",
|
||||
serie_folder="test_serie_4",
|
||||
serie_id="test-serie-4-key",
|
||||
serie_folder="Speed Test (2024)",
|
||||
serie_name="Speed Test",
|
||||
episodes=[EpisodeIdentifier(season=1, episode=1)],
|
||||
)
|
||||
@@ -305,9 +310,10 @@ class TestDownloadProgressWebSocket:
|
||||
download_svc, progress_svc = download_service
|
||||
# Don't subscribe to any events
|
||||
|
||||
# Note: serie_id uses provider key format (URL-safe, lowercase)
|
||||
await download_svc.add_to_queue(
|
||||
serie_id="test_serie_5",
|
||||
serie_folder="test_serie_5",
|
||||
serie_id="test-serie-5-key",
|
||||
serie_folder="No Broadcast Test (2024)",
|
||||
serie_name="No Broadcast Test",
|
||||
episodes=[EpisodeIdentifier(season=1, episode=1)],
|
||||
)
|
||||
@@ -334,9 +340,10 @@ class TestDownloadProgressWebSocket:
|
||||
|
||||
progress_svc.subscribe("progress_updated", failing_handler)
|
||||
|
||||
# Note: serie_id uses provider key format (URL-safe, lowercase)
|
||||
await download_svc.add_to_queue(
|
||||
serie_id="test_serie_6",
|
||||
serie_folder="test_serie_6",
|
||||
serie_id="test-serie-6-key",
|
||||
serie_folder="Error Handling Test (2024)",
|
||||
serie_name="Error Handling Test",
|
||||
episodes=[EpisodeIdentifier(season=1, episode=1)],
|
||||
)
|
||||
@@ -369,9 +376,10 @@ class TestDownloadProgressWebSocket:
|
||||
progress_svc.subscribe("progress_updated", mock_event_handler)
|
||||
|
||||
# Add multiple episodes
|
||||
# Note: serie_id uses provider key format (URL-safe, lowercase)
|
||||
item_ids = await download_svc.add_to_queue(
|
||||
serie_id="test_serie_7",
|
||||
serie_folder="test_serie_7",
|
||||
serie_id="test-serie-7-key",
|
||||
serie_folder="Multi Episode Test (2024)",
|
||||
serie_name="Multi Episode Test",
|
||||
episodes=[
|
||||
EpisodeIdentifier(season=1, episode=1),
|
||||
@@ -418,9 +426,10 @@ class TestDownloadProgressWebSocket:
|
||||
|
||||
progress_svc.subscribe("progress_updated", mock_event_handler)
|
||||
|
||||
# Note: serie_id uses provider key format (URL-safe, lowercase)
|
||||
await download_svc.add_to_queue(
|
||||
serie_id="test_serie_8",
|
||||
serie_folder="test_serie_8",
|
||||
serie_id="test-serie-8-key",
|
||||
serie_folder="Model Test (2024)",
|
||||
serie_name="Model Test",
|
||||
episodes=[EpisodeIdentifier(season=1, episode=1)],
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user