fix tests
This commit is contained in:
parent
8ae8b0cdfb
commit
f91875f6fc
104
fix_tests.py
Normal file
104
fix_tests.py
Normal file
@ -0,0 +1,104 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Script to batch fix common test issues after API changes."""
|
||||
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def fix_add_to_queue_calls(content: str) -> str:
|
||||
"""Add serie_folder parameter to add_to_queue calls."""
|
||||
# Pattern: add_to_queue(\n serie_id="...",
|
||||
# Add: serie_folder="...",
|
||||
pattern = r'(add_to_queue\(\s+serie_id="([^"]+)",)'
|
||||
|
||||
def replace_func(match):
|
||||
serie_id = match.group(2)
|
||||
# Extract just the series name without number if present
|
||||
serie_folder = serie_id.split('-')[0] if '-' in serie_id else serie_id
|
||||
return f'{match.group(1)}\n serie_folder="{serie_folder}",'
|
||||
|
||||
return re.sub(pattern, replace_func, content)
|
||||
|
||||
|
||||
def fix_queue_status_response(content: str) -> str:
|
||||
"""Fix queue status response structure - remove nested 'status' key."""
|
||||
# Replace data["status"]["pending"] with data["pending_queue"]
|
||||
content = re.sub(r'data\["status"\]\["pending"\]', 'data["pending_queue"]', content)
|
||||
content = re.sub(r'data\["status"\]\["active"\]', 'data["active_downloads"]', content)
|
||||
content = re.sub(r'data\["status"\]\["completed"\]', 'data["completed_downloads"]', content)
|
||||
content = re.sub(r'data\["status"\]\["failed"\]', 'data["failed_downloads"]', content)
|
||||
content = re.sub(r'data\["status"\]\["is_running"\]', 'data["is_running"]', content)
|
||||
content = re.sub(r'data\["status"\]\["is_paused"\]', 'data["is_paused"]', content)
|
||||
|
||||
# Also fix response.json()["status"]["..."]
|
||||
content = re.sub(r'response\.json\(\)\["status"\]\["pending"\]', 'response.json()["pending_queue"]', content)
|
||||
content = re.sub(r'response\.json\(\)\["status"\]\["is_running"\]', 'response.json()["is_running"]', content)
|
||||
content = re.sub(r'status\.json\(\)\["status"\]\["is_running"\]', 'status.json()["is_running"]', content)
|
||||
content = re.sub(r'status\.json\(\)\["status"\]\["failed"\]', 'status.json()["failed_downloads"]', content)
|
||||
content = re.sub(r'status\.json\(\)\["status"\]\["completed"\]', 'status.json()["completed_downloads"]', content)
|
||||
|
||||
# Fix assert "status" in data
|
||||
content = re.sub(r'assert "status" in data', 'assert "is_running" in data', content)
|
||||
|
||||
return content
|
||||
|
||||
|
||||
def fix_anime_service_init(content: str) -> str:
|
||||
"""Fix AnimeService initialization in test fixtures."""
|
||||
# This one is complex, so we'll just note files that need manual review
|
||||
if 'AnimeService(' in content and 'directory=' in content:
|
||||
print(" ⚠️ Contains AnimeService with directory= parameter - needs manual review")
|
||||
return content
|
||||
|
||||
|
||||
def main():
|
||||
test_dir = Path(__file__).parent / "tests"
|
||||
|
||||
if not test_dir.exists():
|
||||
print(f"Error: {test_dir} not found")
|
||||
sys.exit(1)
|
||||
|
||||
files_to_fix = [
|
||||
# Download service tests
|
||||
"unit/test_download_service.py",
|
||||
"unit/test_download_progress_websocket.py",
|
||||
"integration/test_download_progress_integration.py",
|
||||
"integration/test_websocket_integration.py",
|
||||
# API tests with queue status
|
||||
"api/test_queue_features.py",
|
||||
"api/test_download_endpoints.py",
|
||||
"frontend/test_existing_ui_integration.py",
|
||||
]
|
||||
|
||||
for file_path in files_to_fix:
|
||||
full_path = test_dir / file_path
|
||||
if not full_path.exists():
|
||||
print(f"Skipping {file_path} (not found)")
|
||||
continue
|
||||
|
||||
print(f"Processing {file_path}...")
|
||||
|
||||
# Read content
|
||||
content = full_path.read_text()
|
||||
original_content = content
|
||||
|
||||
# Apply fixes
|
||||
if 'add_to_queue(' in content:
|
||||
content = fix_add_to_queue_calls(content)
|
||||
|
||||
if 'data["status"]' in content or 'response.json()["status"]' in content:
|
||||
content = fix_queue_status_response(content)
|
||||
|
||||
content = fix_anime_service_init(content)
|
||||
|
||||
# Write back if changed
|
||||
if content != original_content:
|
||||
full_path.write_text(content)
|
||||
print(f" ✓ Updated {file_path}")
|
||||
else:
|
||||
print(f" - No changes needed for {file_path}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@ -74,7 +74,7 @@ class TestQueueDisplay:
|
||||
data = response.json()
|
||||
|
||||
# Verify structure
|
||||
assert "status" in data
|
||||
assert "is_running" in data
|
||||
assert "statistics" in data
|
||||
|
||||
status = data["status"]
|
||||
@ -107,7 +107,7 @@ class TestQueueDisplay:
|
||||
assert response.status_code == 200
|
||||
|
||||
data = response.json()
|
||||
pending = data["status"]["pending"]
|
||||
pending = data["pending_queue"]
|
||||
|
||||
assert len(pending) > 0
|
||||
item = pending[0]
|
||||
@ -140,7 +140,7 @@ class TestQueueReordering:
|
||||
)
|
||||
existing_items = [
|
||||
item["id"]
|
||||
for item in status_response.json()["status"]["pending"]
|
||||
for item in status_response.json()["pending_queue"]
|
||||
]
|
||||
if existing_items:
|
||||
await client.request(
|
||||
@ -190,7 +190,7 @@ class TestQueueReordering:
|
||||
)
|
||||
current_order = [
|
||||
item["id"]
|
||||
for item in status_response.json()["status"]["pending"]
|
||||
for item in status_response.json()["pending_queue"]
|
||||
]
|
||||
|
||||
assert current_order == new_order
|
||||
@ -270,7 +270,7 @@ class TestQueueControl:
|
||||
"/api/queue/status",
|
||||
headers=auth_headers
|
||||
)
|
||||
assert status.json()["status"]["is_running"] is False
|
||||
assert status.json()["is_running"] is False
|
||||
|
||||
# Start queue
|
||||
await client.post("/api/queue/start", headers=auth_headers)
|
||||
@ -280,7 +280,7 @@ class TestQueueControl:
|
||||
"/api/queue/status",
|
||||
headers=auth_headers
|
||||
)
|
||||
assert status.json()["status"]["is_running"] is True
|
||||
assert status.json()["is_running"] is True
|
||||
|
||||
# Stop queue
|
||||
await client.post("/api/queue/stop", headers=auth_headers)
|
||||
@ -290,7 +290,7 @@ class TestQueueControl:
|
||||
"/api/queue/status",
|
||||
headers=auth_headers
|
||||
)
|
||||
assert status.json()["status"]["is_running"] is False
|
||||
assert status.json()["is_running"] is False
|
||||
|
||||
|
||||
class TestCompletedDownloads:
|
||||
@ -323,7 +323,7 @@ class TestCompletedDownloads:
|
||||
data = status.json()
|
||||
|
||||
completed_count = data["statistics"]["completed_count"]
|
||||
completed_list = len(data["status"]["completed"])
|
||||
completed_list = len(data["completed_downloads"])
|
||||
|
||||
# Count should match list length
|
||||
assert completed_count == completed_list
|
||||
@ -390,7 +390,7 @@ class TestFailedDownloads:
|
||||
data = status.json()
|
||||
|
||||
failed_count = data["statistics"]["failed_count"]
|
||||
failed_list = len(data["status"]["failed"])
|
||||
failed_list = len(data["failed_downloads"])
|
||||
|
||||
# Count should match list length
|
||||
assert failed_count == failed_list
|
||||
|
||||
@ -244,7 +244,7 @@ class TestFrontendDownloadAPI:
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
# Check for expected response structure
|
||||
assert "status" in data or "statistics" in data
|
||||
assert "is_running" in data or "statistics" in data
|
||||
|
||||
async def test_start_download_queue(self, authenticated_client):
|
||||
"""Test POST /api/queue/start starts next download."""
|
||||
|
||||
@ -63,15 +63,11 @@ def websocket_service():
|
||||
@pytest.fixture
|
||||
async def anime_service(mock_series_app, progress_service):
|
||||
"""Create an AnimeService."""
|
||||
with patch(
|
||||
"src.server.services.anime_service.SeriesApp",
|
||||
return_value=mock_series_app
|
||||
):
|
||||
service = AnimeService(
|
||||
directory="/test/anime",
|
||||
progress_service=progress_service,
|
||||
)
|
||||
yield service
|
||||
service = AnimeService(
|
||||
series_app=mock_series_app,
|
||||
progress_service=progress_service,
|
||||
)
|
||||
yield service
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@ -130,6 +126,7 @@ class TestDownloadProgressIntegration:
|
||||
# Add download to queue
|
||||
await download_service.add_to_queue(
|
||||
serie_id="integration_test",
|
||||
serie_folder="integration_test",
|
||||
serie_folder="test_folder",
|
||||
serie_name="Integration Test Anime",
|
||||
episodes=[EpisodeIdentifier(season=1, episode=1)],
|
||||
@ -203,6 +200,7 @@ class TestDownloadProgressIntegration:
|
||||
# Add and start download
|
||||
await download_service.add_to_queue(
|
||||
serie_id="client_test",
|
||||
serie_folder="client_test",
|
||||
serie_folder="test_folder",
|
||||
serie_name="Client Test Anime",
|
||||
episodes=[EpisodeIdentifier(season=1, episode=1)],
|
||||
@ -266,6 +264,7 @@ class TestDownloadProgressIntegration:
|
||||
# Start download
|
||||
await download_service.add_to_queue(
|
||||
serie_id="multi_client_test",
|
||||
serie_folder="multi_client_test",
|
||||
serie_folder="test_folder",
|
||||
serie_name="Multi Client Test",
|
||||
episodes=[EpisodeIdentifier(season=1, episode=1)],
|
||||
@ -313,6 +312,7 @@ class TestDownloadProgressIntegration:
|
||||
|
||||
await download_service.add_to_queue(
|
||||
serie_id="structure_test",
|
||||
serie_folder="structure_test",
|
||||
serie_folder="test_folder",
|
||||
serie_name="Structure Test",
|
||||
episodes=[EpisodeIdentifier(season=2, episode=3)],
|
||||
@ -380,6 +380,7 @@ class TestDownloadProgressIntegration:
|
||||
# Start download after disconnect
|
||||
await download_service.add_to_queue(
|
||||
serie_id="disconnect_test",
|
||||
serie_folder="disconnect_test",
|
||||
serie_folder="test_folder",
|
||||
serie_name="Disconnect Test",
|
||||
episodes=[EpisodeIdentifier(season=1, episode=1)],
|
||||
|
||||
@ -47,12 +47,11 @@ def websocket_service():
|
||||
@pytest.fixture
|
||||
async def anime_service(mock_series_app, progress_service):
|
||||
"""Create an AnimeService with mocked dependencies."""
|
||||
with patch("src.server.services.anime_service.SeriesApp", return_value=mock_series_app):
|
||||
service = AnimeService(
|
||||
directory="/test/anime",
|
||||
progress_service=progress_service,
|
||||
)
|
||||
yield service
|
||||
service = AnimeService(
|
||||
series_app=mock_series_app,
|
||||
progress_service=progress_service,
|
||||
)
|
||||
yield service
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@ -86,6 +85,7 @@ class TestWebSocketDownloadIntegration:
|
||||
# Add item to queue
|
||||
item_ids = await download_service.add_to_queue(
|
||||
serie_id="test_serie",
|
||||
serie_folder="test_serie",
|
||||
serie_name="Test Anime",
|
||||
episodes=[EpisodeIdentifier(season=1, episode=1)],
|
||||
priority=DownloadPriority.HIGH,
|
||||
@ -112,6 +112,7 @@ class TestWebSocketDownloadIntegration:
|
||||
# Add items
|
||||
item_ids = await download_service.add_to_queue(
|
||||
serie_id="test",
|
||||
serie_folder="test",
|
||||
serie_name="Test",
|
||||
episodes=[EpisodeIdentifier(season=1, episode=i) for i in range(1, 4)],
|
||||
priority=DownloadPriority.NORMAL,
|
||||
@ -398,6 +399,7 @@ class TestWebSocketEndToEnd:
|
||||
# Add items to queue
|
||||
item_ids = await download_service.add_to_queue(
|
||||
serie_id="test",
|
||||
serie_folder="test",
|
||||
serie_name="Test Anime",
|
||||
episodes=[EpisodeIdentifier(season=1, episode=1)],
|
||||
priority=DownloadPriority.HIGH,
|
||||
|
||||
@ -6,7 +6,7 @@ error handling, and progress reporting integration.
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from unittest.mock import AsyncMock, MagicMock, patch
|
||||
from unittest.mock import AsyncMock, MagicMock
|
||||
|
||||
import pytest
|
||||
|
||||
@ -15,16 +15,17 @@ from src.server.services.progress_service import ProgressService
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_series_app():
|
||||
def mock_series_app(tmp_path):
|
||||
"""Create a mock SeriesApp instance."""
|
||||
with patch("src.server.services.anime_service.SeriesApp") as mock_class:
|
||||
mock_instance = MagicMock()
|
||||
mock_instance.series_list = []
|
||||
mock_instance.search = MagicMock(return_value=[])
|
||||
mock_instance.ReScan = MagicMock()
|
||||
mock_instance.download = MagicMock(return_value=True)
|
||||
mock_class.return_value = mock_instance
|
||||
yield mock_instance
|
||||
mock_instance = MagicMock()
|
||||
mock_instance.directory_to_search = str(tmp_path)
|
||||
mock_instance.series_list = []
|
||||
mock_instance.search = AsyncMock(return_value=[])
|
||||
mock_instance.rescan = AsyncMock()
|
||||
mock_instance.download = AsyncMock(return_value=True)
|
||||
mock_instance.download_status = None
|
||||
mock_instance.scan_status = None
|
||||
return mock_instance
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@ -42,8 +43,7 @@ def mock_progress_service():
|
||||
def anime_service(tmp_path, mock_series_app, mock_progress_service):
|
||||
"""Create an AnimeService instance for testing."""
|
||||
return AnimeService(
|
||||
directory=str(tmp_path),
|
||||
max_workers=2,
|
||||
series_app=mock_series_app,
|
||||
progress_service=mock_progress_service,
|
||||
)
|
||||
|
||||
@ -51,35 +51,38 @@ def anime_service(tmp_path, mock_series_app, mock_progress_service):
|
||||
class TestAnimeServiceInitialization:
|
||||
"""Test AnimeService initialization."""
|
||||
|
||||
def test_initialization_success(self, tmp_path, mock_progress_service):
|
||||
def test_initialization_success(
|
||||
self, mock_series_app, mock_progress_service
|
||||
):
|
||||
"""Test successful service initialization."""
|
||||
with patch("src.server.services.anime_service.SeriesApp"):
|
||||
service = AnimeService(
|
||||
directory=str(tmp_path),
|
||||
max_workers=2,
|
||||
progress_service=mock_progress_service,
|
||||
)
|
||||
|
||||
assert service._directory == str(tmp_path)
|
||||
assert service._executor is not None
|
||||
assert service._progress_service is mock_progress_service
|
||||
service = AnimeService(
|
||||
series_app=mock_series_app,
|
||||
progress_service=mock_progress_service,
|
||||
)
|
||||
|
||||
assert service._app is mock_series_app
|
||||
assert service._progress_service is mock_progress_service
|
||||
|
||||
def test_initialization_failure_raises_error(
|
||||
self, tmp_path, mock_progress_service
|
||||
):
|
||||
"""Test SeriesApp initialization failure raises error."""
|
||||
with patch(
|
||||
"src.server.services.anime_service.SeriesApp"
|
||||
) as mock_class:
|
||||
mock_class.side_effect = Exception("Initialization failed")
|
||||
|
||||
with pytest.raises(
|
||||
AnimeServiceError, match="Initialization failed"
|
||||
):
|
||||
AnimeService(
|
||||
directory=str(tmp_path),
|
||||
progress_service=mock_progress_service,
|
||||
)
|
||||
bad_series_app = MagicMock()
|
||||
bad_series_app.directory_to_search = str(tmp_path)
|
||||
|
||||
# Make event subscription fail
|
||||
def raise_error(*args):
|
||||
raise Exception("Initialization failed")
|
||||
|
||||
bad_series_app.__setattr__ = raise_error
|
||||
|
||||
with pytest.raises(
|
||||
AnimeServiceError, match="Initialization failed"
|
||||
):
|
||||
AnimeService(
|
||||
series_app=bad_series_app,
|
||||
progress_service=mock_progress_service,
|
||||
)
|
||||
|
||||
|
||||
class TestListMissing:
|
||||
@ -321,12 +324,12 @@ class TestConcurrency:
|
||||
class TestFactoryFunction:
|
||||
"""Test factory function."""
|
||||
|
||||
def test_get_anime_service(self, tmp_path):
|
||||
def test_get_anime_service(self):
|
||||
"""Test get_anime_service factory function."""
|
||||
from src.server.services.anime_service import get_anime_service
|
||||
|
||||
# The factory function doesn't take directory anymore
|
||||
service = get_anime_service()
|
||||
|
||||
with patch("src.server.services.anime_service.SeriesApp"):
|
||||
service = get_anime_service(directory=str(tmp_path))
|
||||
|
||||
assert isinstance(service, AnimeService)
|
||||
assert service._directory == str(tmp_path)
|
||||
assert isinstance(service, AnimeService)
|
||||
assert service._app is not None
|
||||
|
||||
@ -48,15 +48,15 @@ class TestDownloadPriority:
|
||||
|
||||
def test_all_priorities_exist(self):
|
||||
"""Test that all expected priorities are defined."""
|
||||
assert DownloadPriority.LOW == "low"
|
||||
assert DownloadPriority.NORMAL == "normal"
|
||||
assert DownloadPriority.HIGH == "high"
|
||||
assert DownloadPriority.LOW == "LOW"
|
||||
assert DownloadPriority.NORMAL == "NORMAL"
|
||||
assert DownloadPriority.HIGH == "HIGH"
|
||||
|
||||
def test_priority_values(self):
|
||||
"""Test that priority values are lowercase strings."""
|
||||
"""Test that priority values are uppercase strings."""
|
||||
for priority in DownloadPriority:
|
||||
assert isinstance(priority.value, str)
|
||||
assert priority.value.islower()
|
||||
assert priority.value.isupper()
|
||||
|
||||
|
||||
class TestEpisodeIdentifier:
|
||||
|
||||
@ -76,15 +76,11 @@ def progress_service():
|
||||
@pytest.fixture
|
||||
async def anime_service(mock_series_app, progress_service):
|
||||
"""Create an AnimeService with mocked dependencies."""
|
||||
with patch(
|
||||
"src.server.services.anime_service.SeriesApp",
|
||||
return_value=mock_series_app
|
||||
):
|
||||
service = AnimeService(
|
||||
directory="/test/anime",
|
||||
progress_service=progress_service,
|
||||
)
|
||||
yield service
|
||||
service = AnimeService(
|
||||
series_app=mock_series_app,
|
||||
progress_service=progress_service,
|
||||
)
|
||||
yield service
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@ -118,7 +114,7 @@ class TestDownloadProgressWebSocket:
|
||||
# Add item to queue
|
||||
item_ids = await download_service.add_to_queue(
|
||||
serie_id="test_serie_1",
|
||||
serie_folder="test_folder",
|
||||
serie_folder="test_serie_1",
|
||||
serie_name="Test Anime",
|
||||
episodes=[EpisodeIdentifier(season=1, episode=1)],
|
||||
priority=DownloadPriority.NORMAL,
|
||||
@ -168,7 +164,7 @@ class TestDownloadProgressWebSocket:
|
||||
# Add item with specific episode info
|
||||
await download_service.add_to_queue(
|
||||
serie_id="test_serie_2",
|
||||
serie_folder="test_folder",
|
||||
serie_folder="test_serie_2",
|
||||
serie_name="My Test Anime",
|
||||
episodes=[EpisodeIdentifier(season=2, episode=5)],
|
||||
priority=DownloadPriority.HIGH,
|
||||
@ -203,7 +199,7 @@ class TestDownloadProgressWebSocket:
|
||||
|
||||
await download_service.add_to_queue(
|
||||
serie_id="test_serie_3",
|
||||
serie_folder="test_folder",
|
||||
serie_folder="test_serie_3",
|
||||
serie_name="Progress Test",
|
||||
episodes=[EpisodeIdentifier(season=1, episode=1)],
|
||||
)
|
||||
@ -240,7 +236,7 @@ class TestDownloadProgressWebSocket:
|
||||
|
||||
await download_service.add_to_queue(
|
||||
serie_id="test_serie_4",
|
||||
serie_folder="test_folder",
|
||||
serie_folder="test_serie_4",
|
||||
serie_name="Speed Test",
|
||||
episodes=[EpisodeIdentifier(season=1, episode=1)],
|
||||
)
|
||||
@ -272,7 +268,7 @@ class TestDownloadProgressWebSocket:
|
||||
|
||||
await download_service.add_to_queue(
|
||||
serie_id="test_serie_5",
|
||||
serie_folder="test_folder",
|
||||
serie_folder="test_serie_5",
|
||||
serie_name="No Broadcast Test",
|
||||
episodes=[EpisodeIdentifier(season=1, episode=1)],
|
||||
)
|
||||
@ -300,7 +296,7 @@ class TestDownloadProgressWebSocket:
|
||||
|
||||
await download_service.add_to_queue(
|
||||
serie_id="test_serie_6",
|
||||
serie_folder="test_folder",
|
||||
serie_folder="test_serie_6",
|
||||
serie_name="Error Handling Test",
|
||||
episodes=[EpisodeIdentifier(season=1, episode=1)],
|
||||
)
|
||||
@ -331,7 +327,7 @@ class TestDownloadProgressWebSocket:
|
||||
# Add multiple episodes
|
||||
item_ids = await download_service.add_to_queue(
|
||||
serie_id="test_serie_7",
|
||||
serie_folder="test_folder",
|
||||
serie_folder="test_serie_7",
|
||||
serie_name="Multi Episode Test",
|
||||
episodes=[
|
||||
EpisodeIdentifier(season=1, episode=1),
|
||||
@ -378,7 +374,7 @@ class TestDownloadProgressWebSocket:
|
||||
|
||||
await download_service.add_to_queue(
|
||||
serie_id="test_serie_8",
|
||||
serie_folder="test_folder",
|
||||
serie_folder="test_serie_8",
|
||||
serie_name="Model Test",
|
||||
episodes=[EpisodeIdentifier(season=1, episode=1)],
|
||||
)
|
||||
|
||||
@ -118,6 +118,7 @@ class TestQueueManagement:
|
||||
|
||||
item_ids = await download_service.add_to_queue(
|
||||
serie_id="series-1",
|
||||
serie_folder="series",
|
||||
serie_name="Test Series",
|
||||
episodes=episodes,
|
||||
priority=DownloadPriority.NORMAL,
|
||||
@ -142,6 +143,7 @@ class TestQueueManagement:
|
||||
|
||||
item_ids = await download_service.add_to_queue(
|
||||
serie_id="series-1",
|
||||
serie_folder="series",
|
||||
serie_name="Test Series",
|
||||
episodes=episodes,
|
||||
priority=DownloadPriority.NORMAL,
|
||||
@ -155,6 +157,7 @@ class TestQueueManagement:
|
||||
"""Test removing items from pending queue."""
|
||||
item_ids = await download_service.add_to_queue(
|
||||
serie_id="series-1",
|
||||
serie_folder="series",
|
||||
serie_name="Test Series",
|
||||
episodes=[EpisodeIdentifier(season=1, episode=1)],
|
||||
)
|
||||
@ -171,6 +174,7 @@ class TestQueueManagement:
|
||||
# Add items to queue
|
||||
item_ids = await download_service.add_to_queue(
|
||||
serie_id="series-1",
|
||||
serie_folder="series",
|
||||
serie_name="Test Series",
|
||||
episodes=[
|
||||
EpisodeIdentifier(season=1, episode=1),
|
||||
@ -200,6 +204,7 @@ class TestQueueManagement:
|
||||
# Add items and start one
|
||||
await download_service.add_to_queue(
|
||||
serie_id="series-1",
|
||||
serie_folder="series",
|
||||
serie_name="Test Series",
|
||||
episodes=[
|
||||
EpisodeIdentifier(season=1, episode=1),
|
||||
@ -236,6 +241,7 @@ class TestQueueManagement:
|
||||
# Add item
|
||||
await download_service.add_to_queue(
|
||||
serie_id="series-1",
|
||||
serie_folder="series",
|
||||
serie_name="Test Series",
|
||||
episodes=[EpisodeIdentifier(season=1, episode=1)],
|
||||
)
|
||||
@ -258,6 +264,7 @@ class TestQueueManagement:
|
||||
# Add item
|
||||
await download_service.add_to_queue(
|
||||
serie_id="series-1",
|
||||
serie_folder="series",
|
||||
serie_name="Test Series",
|
||||
episodes=[EpisodeIdentifier(season=1, episode=1)],
|
||||
)
|
||||
@ -279,6 +286,7 @@ class TestQueueStatus:
|
||||
# Add items to queue
|
||||
await download_service.add_to_queue(
|
||||
serie_id="series-1",
|
||||
serie_folder="series",
|
||||
serie_name="Test Series",
|
||||
episodes=[
|
||||
EpisodeIdentifier(season=1, episode=1),
|
||||
@ -302,6 +310,7 @@ class TestQueueStatus:
|
||||
# Add items
|
||||
await download_service.add_to_queue(
|
||||
serie_id="series-1",
|
||||
serie_folder="series",
|
||||
serie_name="Test Series",
|
||||
episodes=[
|
||||
EpisodeIdentifier(season=1, episode=1),
|
||||
@ -380,6 +389,7 @@ class TestPersistence:
|
||||
"""Test that queue state is persisted to disk."""
|
||||
await download_service.add_to_queue(
|
||||
serie_id="series-1",
|
||||
serie_folder="series",
|
||||
serie_name="Test Series",
|
||||
episodes=[EpisodeIdentifier(season=1, episode=1)],
|
||||
)
|
||||
@ -408,6 +418,7 @@ class TestPersistence:
|
||||
|
||||
await service1.add_to_queue(
|
||||
serie_id="series-1",
|
||||
serie_folder="series",
|
||||
serie_name="Test Series",
|
||||
episodes=[
|
||||
EpisodeIdentifier(season=1, episode=1),
|
||||
@ -491,6 +502,7 @@ class TestBroadcastCallbacks:
|
||||
|
||||
await download_service.add_to_queue(
|
||||
serie_id="series-1",
|
||||
serie_folder="series",
|
||||
serie_name="Test Series",
|
||||
episodes=[EpisodeIdentifier(season=1, episode=1)],
|
||||
)
|
||||
@ -530,6 +542,7 @@ class TestBroadcastCallbacks:
|
||||
# Add an item to the queue
|
||||
await download_service.add_to_queue(
|
||||
serie_id="series-1",
|
||||
serie_folder="series",
|
||||
serie_name="Test Series",
|
||||
episodes=[EpisodeIdentifier(season=1, episode=1)],
|
||||
)
|
||||
@ -617,6 +630,7 @@ class TestErrorHandling:
|
||||
|
||||
await download_service.add_to_queue(
|
||||
serie_id="series-1",
|
||||
serie_folder="series",
|
||||
serie_name="Test Series",
|
||||
episodes=[EpisodeIdentifier(season=1, episode=1)],
|
||||
)
|
||||
|
||||
@ -7,11 +7,10 @@ Tests the functionality of SeriesApp including:
|
||||
- Download with progress callbacks
|
||||
- Directory scanning with progress reporting
|
||||
- Async versions of operations
|
||||
- Cancellation support
|
||||
- Error handling
|
||||
"""
|
||||
|
||||
from unittest.mock import Mock, patch
|
||||
from unittest.mock import AsyncMock, Mock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
@ -35,62 +34,30 @@ class TestSeriesAppInitialization:
|
||||
|
||||
# Verify initialization
|
||||
assert app.directory_to_search == test_dir
|
||||
assert app._operation_status == OperationStatus.IDLE
|
||||
assert app._cancel_flag is False
|
||||
assert app._current_operation is None
|
||||
mock_loaders.assert_called_once()
|
||||
mock_scanner.assert_called_once()
|
||||
|
||||
@patch('src.core.SeriesApp.Loaders')
|
||||
@patch('src.core.SeriesApp.SerieScanner')
|
||||
@patch('src.core.SeriesApp.SerieList')
|
||||
def test_init_with_callbacks(
|
||||
self, mock_serie_list, mock_scanner, mock_loaders
|
||||
):
|
||||
"""Test initialization with progress and error callbacks."""
|
||||
def test_init_failure_raises_error(self, mock_loaders):
|
||||
"""Test that initialization failure raises error."""
|
||||
test_dir = "/test/anime"
|
||||
progress_callback = Mock()
|
||||
error_callback = Mock()
|
||||
|
||||
# Create app with callbacks
|
||||
app = SeriesApp(
|
||||
test_dir,
|
||||
progress_callback=progress_callback,
|
||||
error_callback=error_callback
|
||||
)
|
||||
|
||||
# Verify callbacks are stored
|
||||
assert app.progress_callback == progress_callback
|
||||
assert app.error_callback == error_callback
|
||||
|
||||
@patch('src.core.SeriesApp.Loaders')
|
||||
def test_init_failure_calls_error_callback(self, mock_loaders):
|
||||
"""Test that initialization failure triggers error callback."""
|
||||
test_dir = "/test/anime"
|
||||
error_callback = Mock()
|
||||
|
||||
# Make Loaders raise an exception
|
||||
mock_loaders.side_effect = RuntimeError("Init failed")
|
||||
|
||||
# Create app should raise but call error callback
|
||||
# Create app should raise
|
||||
with pytest.raises(RuntimeError):
|
||||
SeriesApp(test_dir, error_callback=error_callback)
|
||||
|
||||
# Verify error callback was called
|
||||
error_callback.assert_called_once()
|
||||
assert isinstance(
|
||||
error_callback.call_args[0][0],
|
||||
RuntimeError
|
||||
)
|
||||
SeriesApp(test_dir)
|
||||
|
||||
|
||||
class TestSeriesAppSearch:
|
||||
"""Test search functionality."""
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch('src.core.SeriesApp.Loaders')
|
||||
@patch('src.core.SeriesApp.SerieScanner')
|
||||
@patch('src.core.SeriesApp.SerieList')
|
||||
def test_search_success(
|
||||
async def test_search_success(
|
||||
self, mock_serie_list, mock_scanner, mock_loaders
|
||||
):
|
||||
"""Test successful search."""
|
||||
@ -104,34 +71,32 @@ class TestSeriesAppSearch:
|
||||
]
|
||||
app.loader.search = Mock(return_value=expected_results)
|
||||
|
||||
# Perform search
|
||||
results = app.search("test anime")
|
||||
# Perform search (now async)
|
||||
results = await app.search("test anime")
|
||||
|
||||
# Verify results
|
||||
assert results == expected_results
|
||||
app.loader.search.assert_called_once_with("test anime")
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch('src.core.SeriesApp.Loaders')
|
||||
@patch('src.core.SeriesApp.SerieScanner')
|
||||
@patch('src.core.SeriesApp.SerieList')
|
||||
def test_search_failure_calls_error_callback(
|
||||
async def test_search_failure_raises_error(
|
||||
self, mock_serie_list, mock_scanner, mock_loaders
|
||||
):
|
||||
"""Test search failure triggers error callback."""
|
||||
"""Test search failure raises error."""
|
||||
test_dir = "/test/anime"
|
||||
error_callback = Mock()
|
||||
app = SeriesApp(test_dir, error_callback=error_callback)
|
||||
app = SeriesApp(test_dir)
|
||||
|
||||
# Make search raise an exception
|
||||
app.loader.search = Mock(
|
||||
side_effect=RuntimeError("Search failed")
|
||||
)
|
||||
|
||||
# Search should raise and call error callback
|
||||
# Search should raise
|
||||
with pytest.raises(RuntimeError):
|
||||
app.search("test")
|
||||
|
||||
error_callback.assert_called_once()
|
||||
await app.search("test")
|
||||
|
||||
|
||||
class TestSeriesAppDownload:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user