Fix: Remove episodes from missing list on download/rescan

- Update _update_series_in_db to sync missing episodes bidirectionally
- Add delete_by_series_and_episode method to EpisodeService
- Remove downloaded episodes from DB after successful download
- Clear anime service cache when episodes are removed
- Fix tests to use 'message' instead of 'detail' in API responses
- Mock DB operations in rescan tests
This commit is contained in:
2025-12-15 16:17:34 +01:00
parent bf332f27e0
commit 4c9bf6b982
8 changed files with 182 additions and 33 deletions

View File

@@ -236,7 +236,7 @@ async def test_add_to_queue_service_error(
)
assert response.status_code == 400
assert "Queue full" in response.json()["detail"]
assert "Queue full" in response.json()["message"]
@pytest.mark.asyncio
@@ -294,8 +294,8 @@ async def test_start_download_empty_queue(
assert response.status_code == 400
data = response.json()
detail = data["detail"].lower()
assert "empty" in detail or "no pending" in detail
message = data["message"].lower()
assert "empty" in message or "no pending" in message
@pytest.mark.asyncio
@@ -311,8 +311,8 @@ async def test_start_download_already_active(
assert response.status_code == 400
data = response.json()
detail_lower = data["detail"].lower()
assert "already" in detail_lower or "progress" in detail_lower
message_lower = data["message"].lower()
assert "already" in message_lower or "progress" in message_lower
@pytest.mark.asyncio

View File

@@ -201,7 +201,7 @@ class TestFrontendAnimeAPI:
async def test_rescan_anime(self, authenticated_client):
"""Test POST /api/anime/rescan triggers rescan with events."""
from unittest.mock import MagicMock
from unittest.mock import MagicMock, patch
from src.server.services.progress_service import ProgressService
from src.server.utils.dependencies import get_anime_service
@@ -210,7 +210,7 @@ class TestFrontendAnimeAPI:
mock_series_app = MagicMock()
mock_series_app.directory_to_search = "/tmp/test"
mock_series_app.series_list = []
mock_series_app.rescan = AsyncMock()
mock_series_app.rescan = AsyncMock(return_value=[])
mock_series_app.download_status = None
mock_series_app.scan_status = None
@@ -232,7 +232,16 @@ class TestFrontendAnimeAPI:
app.dependency_overrides[get_anime_service] = lambda: anime_service
try:
response = await authenticated_client.post("/api/anime/rescan")
# Mock database operations called during rescan
with patch.object(
anime_service, '_save_scan_results_to_db', new_callable=AsyncMock
):
with patch.object(
anime_service, '_load_series_from_db', new_callable=AsyncMock
):
response = await authenticated_client.post(
"/api/anime/rescan"
)
assert response.status_code == 200
data = response.json()
@@ -448,7 +457,7 @@ class TestFrontendJavaScriptIntegration:
assert response.status_code in [200, 400]
if response.status_code == 400:
# Verify error message indicates empty queue
assert "No pending downloads" in response.json()["detail"]
assert "No pending downloads" in response.json()["message"]
# Test pause - always succeeds even if nothing is processing
response = await authenticated_client.post("/api/queue/pause")

View File

@@ -220,7 +220,8 @@ class TestDownloadFlowEndToEnd:
assert response.status_code == 400
data = response.json()
assert "detail" in data
# API returns 'message' for error responses
assert "message" in data
async def test_validation_error_for_invalid_priority(self, authenticated_client):
"""Test validation error for invalid priority level."""

View File

@@ -6,7 +6,7 @@ real-time updates are properly broadcasted to connected clients.
"""
import asyncio
from typing import Any, Dict, List
from unittest.mock import Mock, patch
from unittest.mock import AsyncMock, Mock, patch
import pytest
@@ -64,6 +64,9 @@ async def anime_service(mock_series_app, progress_service):
series_app=mock_series_app,
progress_service=progress_service,
)
# Mock database operations that are called during rescan
service._save_scan_results_to_db = AsyncMock(return_value=0)
service._load_series_from_db = AsyncMock(return_value=None)
yield service

View File

@@ -1,9 +1,9 @@
"""Tests for SerieList class - identifier standardization."""
# pylint: disable=redefined-outer-name
import os
import tempfile
import warnings
from unittest.mock import MagicMock, patch
import pytest