youtube-web/server/tests/test_queue_api.py

178 lines
6.0 KiB
Python

"""Tests for queue API endpoints - verify the Flask routes work correctly."""
import json
import os
import sys
import tempfile
from pathlib import Path
from unittest.mock import MagicMock
sys.path.insert(0, str(Path(__file__).parent.parent))
from flask import Flask
from models import QueueItem
from models.queue_store import QueueStore
def create_app(store):
"""Create a minimal Flask app with queue routes for testing."""
app = Flask(__name__)
app.config["queue_store"] = store
# Create a mock download engine that actually adds to store
def mock_enqueue(item):
store.add_item(item)
mock_engine = MagicMock()
mock_engine.enqueue_download = mock_enqueue
# Create a mock yt_cli
mock_yt_cli = MagicMock()
mock_yt_cli.config = {"download_dir": "/tmp"}
# Mock the app module imports
import sys as test_sys
mock_app_module = MagicMock()
mock_app_module.queue_store = store
mock_app_module.download_engine = mock_engine
mock_app_module.yt_cli = mock_yt_cli
test_sys.modules["app"] = mock_app_module
from routes.queue import queue_bp
app.register_blueprint(queue_bp)
return app
def test_queue_api_get_empty():
"""Test GET /api/queue returns empty queue."""
with tempfile.TemporaryDirectory() as tmpdir:
path = os.path.join(tmpdir, "test_queue.json")
store = QueueStore(store_path=path)
app = create_app(store)
with app.test_client() as client:
resp = client.get("/api/queue")
assert resp.status_code == 200
data = json.loads(resp.data)
assert data["total"] == 0
assert data["queue"] == []
assert data["pendingCount"] == 0
assert data["downloadingCount"] == 0
print("PASS: test_queue_api_get_empty")
def test_queue_api_add_and_get():
"""Test POST /api/queue then GET /api/queue."""
with tempfile.TemporaryDirectory() as tmpdir:
path = os.path.join(tmpdir, "test_queue.json")
store = QueueStore(store_path=path)
app = create_app(store)
with app.test_client() as client:
resp = client.post("/api/queue", json={
"videoId": "test123",
"title": "Test Video",
"thumbnail": "https://img.youtube.com/vi/test123/hqdefault.jpg",
"category": "General",
"url": "https://www.youtube.com/watch?v=test123",
"quality": "1080"
})
assert resp.status_code == 202
data = json.loads(resp.data)
assert data["videoId"] == "test123"
assert data["category"] == "General"
resp = client.get("/api/queue")
assert resp.status_code == 200
data = json.loads(resp.data)
assert data["total"] >= 1
assert any(item["videoId"] == "test123" for item in data["queue"])
print("PASS: test_queue_api_add_and_get")
def test_queue_api_remove():
"""Test DELETE /api/queue/<id>."""
with tempfile.TemporaryDirectory() as tmpdir:
path = os.path.join(tmpdir, "test_queue.json")
store = QueueStore(store_path=path)
item = QueueItem(
id="rmtest1",
video_id="vid1",
title="Remove Me",
url="https://youtube.com/watch?v=vid1",
category="General"
)
store.add_item(item)
app = create_app(store)
with app.test_client() as client:
resp = client.delete("/api/queue/rmtest1")
assert resp.status_code == 200
resp = client.get("/api/queue")
assert resp.status_code == 200
data = json.loads(resp.data)
assert data["total"] == 0
print("PASS: test_queue_api_remove")
def test_queue_api_clear():
"""Test DELETE /api/queue clears all items."""
with tempfile.TemporaryDirectory() as tmpdir:
path = os.path.join(tmpdir, "test_queue.json")
store = QueueStore(store_path=path)
store.add_item(QueueItem(id="a", video_id="1", title="A", url="https://y.com/1"))
store.add_item(QueueItem(id="b", video_id="2", title="B", url="https://y.com/2"))
app = create_app(store)
with app.test_client() as client:
resp = client.delete("/api/queue")
assert resp.status_code == 200
data = json.loads(resp.data)
assert data["count"] == 2
resp = client.get("/api/queue")
assert resp.status_code == 200
data = json.loads(resp.data)
assert data["total"] == 0
print("PASS: test_queue_api_clear")
def test_queue_api_corrupted_file_recovery():
"""Test that the queue API recovers from corrupted JSON file."""
with tempfile.TemporaryDirectory() as tmpdir:
path = os.path.join(tmpdir, "test_queue.json")
with open(path, "w") as f:
f.write('{"corrupted": true, "invalid": "char \x00 here"}')
store = QueueStore(store_path=path)
app = create_app(store)
with app.test_client() as client:
resp = client.get("/api/queue")
assert resp.status_code == 200
data = json.loads(resp.data)
assert data["total"] == 0
assert data["queue"] == []
print("PASS: test_queue_api_corrupted_file_recovery")
def test_queue_api_missing_url():
"""Test POST /api/queue returns 400 when URL is missing."""
with tempfile.TemporaryDirectory() as tmpdir:
path = os.path.join(tmpdir, "test_queue.json")
store = QueueStore(store_path=path)
app = create_app(store)
with app.test_client() as client:
resp = client.post("/api/queue", json={"videoId": "x", "title": "No URL"})
assert resp.status_code == 400
print("PASS: test_queue_api_missing_url")
if __name__ == "__main__":
test_queue_api_get_empty()
test_queue_api_add_and_get()
test_queue_api_remove()
test_queue_api_clear()
test_queue_api_corrupted_file_recovery()
test_queue_api_missing_url()
print("\nAll API tests passed!")