fix tests
This commit is contained in:
@@ -5,10 +5,10 @@ including adding episodes, removing items, controlling queue processing, and
|
||||
retrieving queue status and statistics.
|
||||
"""
|
||||
from fastapi import APIRouter, Depends, HTTPException, Path, status
|
||||
from fastapi.responses import JSONResponse
|
||||
|
||||
from src.server.models.download import (
|
||||
DownloadRequest,
|
||||
DownloadResponse,
|
||||
QueueOperationRequest,
|
||||
QueueReorderRequest,
|
||||
QueueStatusResponse,
|
||||
@@ -44,7 +44,30 @@ async def get_queue_status(
|
||||
queue_status = await download_service.get_queue_status()
|
||||
queue_stats = await download_service.get_queue_stats()
|
||||
|
||||
return QueueStatusResponse(status=queue_status, statistics=queue_stats)
|
||||
# Provide a legacy-shaped status payload expected by older clients
|
||||
# and integration tests. Map internal model fields to the older keys.
|
||||
status_payload = {
|
||||
"is_running": queue_status.is_running,
|
||||
"is_paused": queue_status.is_paused,
|
||||
"active": [it.model_dump(mode="json") for it in queue_status.active_downloads],
|
||||
"pending": [it.model_dump(mode="json") for it in queue_status.pending_queue],
|
||||
"completed": [it.model_dump(mode="json") for it in queue_status.completed_downloads],
|
||||
"failed": [it.model_dump(mode="json") for it in queue_status.failed_downloads],
|
||||
}
|
||||
|
||||
# Add success_rate to statistics for backward compatibility
|
||||
completed = queue_stats.completed_count
|
||||
failed = queue_stats.failed_count
|
||||
success_rate = None
|
||||
if (completed + failed) > 0:
|
||||
success_rate = completed / (completed + failed)
|
||||
|
||||
stats_payload = queue_stats.model_dump(mode="json")
|
||||
stats_payload["success_rate"] = success_rate
|
||||
|
||||
return JSONResponse(
|
||||
content={"status": status_payload, "statistics": stats_payload}
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
raise HTTPException(
|
||||
@@ -53,11 +76,7 @@ async def get_queue_status(
|
||||
)
|
||||
|
||||
|
||||
@router.post(
|
||||
"/add",
|
||||
response_model=DownloadResponse,
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
)
|
||||
@router.post("/add", status_code=status.HTTP_201_CREATED)
|
||||
async def add_to_queue(
|
||||
request: DownloadRequest,
|
||||
_: dict = Depends(require_auth),
|
||||
@@ -98,12 +117,18 @@ async def add_to_queue(
|
||||
priority=request.priority,
|
||||
)
|
||||
|
||||
return DownloadResponse(
|
||||
status="success",
|
||||
message=f"Added {len(added_ids)} episode(s) to download queue",
|
||||
added_items=added_ids,
|
||||
failed_items=[],
|
||||
)
|
||||
# Keep a backwards-compatible response shape and return it as a
|
||||
# raw JSONResponse so FastAPI won't coerce it based on any
|
||||
# response_model defined elsewhere.
|
||||
payload = {
|
||||
"status": "success",
|
||||
"message": f"Added {len(added_ids)} episode(s) to download queue",
|
||||
"added_items": added_ids,
|
||||
"item_ids": added_ids,
|
||||
"failed_items": [],
|
||||
}
|
||||
|
||||
return JSONResponse(content=payload, status_code=status.HTTP_201_CREATED)
|
||||
|
||||
except DownloadServiceError as e:
|
||||
raise HTTPException(
|
||||
@@ -378,9 +403,55 @@ async def resume_queue(
|
||||
)
|
||||
|
||||
|
||||
# Backwards-compatible control endpoints (some integration tests and older
|
||||
# clients call `/api/queue/control/<action>`). These simply proxy to the
|
||||
# existing handlers above to avoid duplicating service logic.
|
||||
|
||||
|
||||
@router.post("/control/start", status_code=status.HTTP_200_OK)
|
||||
async def control_start(
|
||||
_: dict = Depends(require_auth),
|
||||
download_service: DownloadService = Depends(get_download_service),
|
||||
):
|
||||
return await start_queue(_, download_service)
|
||||
|
||||
|
||||
@router.post("/control/stop", status_code=status.HTTP_200_OK)
|
||||
async def control_stop(
|
||||
_: dict = Depends(require_auth),
|
||||
download_service: DownloadService = Depends(get_download_service),
|
||||
):
|
||||
return await stop_queue(_, download_service)
|
||||
|
||||
|
||||
@router.post("/control/pause", status_code=status.HTTP_200_OK)
|
||||
async def control_pause(
|
||||
_: dict = Depends(require_auth),
|
||||
download_service: DownloadService = Depends(get_download_service),
|
||||
):
|
||||
return await pause_queue(_, download_service)
|
||||
|
||||
|
||||
@router.post("/control/resume", status_code=status.HTTP_200_OK)
|
||||
async def control_resume(
|
||||
_: dict = Depends(require_auth),
|
||||
download_service: DownloadService = Depends(get_download_service),
|
||||
):
|
||||
return await resume_queue(_, download_service)
|
||||
|
||||
|
||||
@router.post("/control/clear_completed", status_code=status.HTTP_200_OK)
|
||||
async def control_clear_completed(
|
||||
_: dict = Depends(require_auth),
|
||||
download_service: DownloadService = Depends(get_download_service),
|
||||
):
|
||||
# Call the existing clear_completed implementation which returns a dict
|
||||
return await clear_completed(_, download_service)
|
||||
|
||||
|
||||
@router.post("/reorder", status_code=status.HTTP_200_OK)
|
||||
async def reorder_queue(
|
||||
request: QueueReorderRequest,
|
||||
request: dict,
|
||||
_: dict = Depends(require_auth),
|
||||
download_service: DownloadService = Depends(get_download_service),
|
||||
):
|
||||
@@ -403,15 +474,43 @@ async def reorder_queue(
|
||||
400 for invalid request, 500 on service error
|
||||
"""
|
||||
try:
|
||||
success = await download_service.reorder_queue(
|
||||
item_id=request.item_id,
|
||||
new_position=request.new_position,
|
||||
)
|
||||
# Support legacy bulk reorder payload used by some integration tests:
|
||||
# {"item_order": ["id1", "id2", ...]}
|
||||
if "item_order" in request:
|
||||
item_order = request.get("item_order", [])
|
||||
if not isinstance(item_order, list):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail="item_order must be a list of item IDs",
|
||||
)
|
||||
|
||||
success = await download_service.reorder_queue_bulk(item_order)
|
||||
else:
|
||||
# Fallback to single-item reorder shape
|
||||
# Validate request
|
||||
try:
|
||||
req = QueueReorderRequest(**request)
|
||||
except Exception as e:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
||||
detail=str(e),
|
||||
)
|
||||
|
||||
success = await download_service.reorder_queue(
|
||||
item_id=req.item_id,
|
||||
new_position=req.new_position,
|
||||
)
|
||||
|
||||
if not success:
|
||||
# Provide an appropriate 404 message depending on request shape
|
||||
if "item_order" in request:
|
||||
detail = "One or more items in item_order were not found in pending queue"
|
||||
else:
|
||||
detail = f"Item {req.item_id} not found in pending queue"
|
||||
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail=f"Item {request.item_id} not found in pending queue",
|
||||
detail=detail,
|
||||
)
|
||||
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user