feat(video-lab): /api/internal/video/update endpoint + tests (SP-8)

UpdatePayload schema (task_id/status/progress/message/video_url/error).
404 if task not found. insta/music-lab과 동일 패턴 + video_url 필드.
Plan-B-Video Phase 1.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-19 08:29:05 +09:00
parent 21cf0114f4
commit e8dbf8092a
2 changed files with 141 additions and 0 deletions

View File

@@ -0,0 +1,89 @@
"""POST /api/internal/video/update — Windows video-render webhook."""
import pytest
from fastapi import FastAPI
from fastapi.testclient import TestClient
from app.internal_router import router
from app import db
@pytest.fixture(autouse=True)
def _set_key(monkeypatch):
monkeypatch.setenv("INTERNAL_API_KEY", "test-secret")
@pytest.fixture
def client(tmp_path, monkeypatch):
monkeypatch.setenv("VIDEO_DATA_DIR", str(tmp_path))
monkeypatch.setattr(db, "DB_PATH", str(tmp_path / "test_video.db"))
db.init_db()
app = FastAPI()
app.include_router(router)
return TestClient(app)
def _make_task():
tid = "video-task-1"
db.create_task(tid, "sora", {"prompt": "test"})
return tid
def test_update_with_valid_key_updates_db(client):
tid = _make_task()
r = client.post(
"/api/internal/video/update",
headers={"X-Internal-Key": "test-secret"},
json={"task_id": tid, "status": "processing", "progress": 30, "message": "downloading"},
)
assert r.status_code == 200
task = db.get_task(tid)
assert task["status"] == "processing"
assert task["progress"] == 30
assert task["message"] == "downloading"
def test_update_with_invalid_key_returns_401(client):
tid = _make_task()
r = client.post(
"/api/internal/video/update",
headers={"X-Internal-Key": "wrong"},
json={"task_id": tid, "status": "processing", "progress": 30},
)
assert r.status_code == 401
def test_update_succeeded_with_video_url(client):
tid = _make_task()
r = client.post(
"/api/internal/video/update",
headers={"X-Internal-Key": "test-secret"},
json={
"task_id": tid, "status": "succeeded", "progress": 100,
"message": "완료", "video_url": "/media/video/video-task-1.mp4",
},
)
assert r.status_code == 200
task = db.get_task(tid)
assert task["status"] == "succeeded"
assert task["video_url"] == "/media/video/video-task-1.mp4"
def test_update_failed_records_error(client):
tid = _make_task()
r = client.post(
"/api/internal/video/update",
headers={"X-Internal-Key": "test-secret"},
json={"task_id": tid, "status": "failed", "progress": 0, "error": "Sora API rate limit"},
)
assert r.status_code == 200
task = db.get_task(tid)
assert task["status"] == "failed"
assert "Sora" in (task.get("error") or "")
def test_update_unknown_task_returns_404(client):
r = client.post(
"/api/internal/video/update",
headers={"X-Internal-Key": "test-secret"},
json={"task_id": "nonexistent", "status": "processing", "progress": 10},
)
assert r.status_code == 404