feat(US3+4): video frame extraction + video-to-text — POST /api/v1/video/*
- app/models/video_models.py: ExtractFramesRequest, VideoToTextRequest, FrameInfo, VideoJobCallback, VideoAcceptedResponse - app/services/video_service.py: interval+keyframe frame extraction, uniform-sample video-to-text, HTTP callback, temp file cleanup - app/routers/video.py: size check helper (_check_video_size via head_object), BackgroundTasks enqueue for both endpoints - tests: 6 service + 4 router tests, 10/10 passing
This commit is contained in:
71
tests/test_video_router.py
Normal file
71
tests/test_video_router.py
Normal file
@@ -0,0 +1,71 @@
|
||||
import pytest
|
||||
from unittest.mock import AsyncMock, patch
|
||||
|
||||
from app.core.exceptions import VideoTooLargeError
|
||||
|
||||
|
||||
def test_extract_frames_returns_202(client, mock_storage):
|
||||
mock_storage.get_object_size = AsyncMock(return_value=10 * 1024 * 1024) # 10 MB
|
||||
|
||||
with patch("app.routers.video.BackgroundTasks.add_task"):
|
||||
resp = client.post(
|
||||
"/api/v1/video/extract-frames",
|
||||
json={
|
||||
"file_path": "video/test.mp4",
|
||||
"source_id": 10,
|
||||
"job_id": 42,
|
||||
},
|
||||
)
|
||||
assert resp.status_code == 202
|
||||
data = resp.json()
|
||||
assert data["job_id"] == 42
|
||||
|
||||
|
||||
def test_extract_frames_video_too_large_returns_400(client, mock_storage):
|
||||
mock_storage.get_object_size = AsyncMock(return_value=300 * 1024 * 1024) # 300 MB > 200 MB
|
||||
|
||||
resp = client.post(
|
||||
"/api/v1/video/extract-frames",
|
||||
json={
|
||||
"file_path": "video/big.mp4",
|
||||
"source_id": 10,
|
||||
"job_id": 99,
|
||||
},
|
||||
)
|
||||
assert resp.status_code == 400
|
||||
assert resp.json()["code"] == "VIDEO_TOO_LARGE"
|
||||
|
||||
|
||||
def test_video_to_text_returns_202(client, mock_storage):
|
||||
mock_storage.get_object_size = AsyncMock(return_value=10 * 1024 * 1024)
|
||||
|
||||
with patch("app.routers.video.BackgroundTasks.add_task"):
|
||||
resp = client.post(
|
||||
"/api/v1/video/to-text",
|
||||
json={
|
||||
"file_path": "video/test.mp4",
|
||||
"source_id": 10,
|
||||
"job_id": 43,
|
||||
"start_sec": 0,
|
||||
"end_sec": 60,
|
||||
},
|
||||
)
|
||||
assert resp.status_code == 202
|
||||
assert resp.json()["job_id"] == 43
|
||||
|
||||
|
||||
def test_video_to_text_too_large_returns_400(client, mock_storage):
|
||||
mock_storage.get_object_size = AsyncMock(return_value=300 * 1024 * 1024)
|
||||
|
||||
resp = client.post(
|
||||
"/api/v1/video/to-text",
|
||||
json={
|
||||
"file_path": "video/big.mp4",
|
||||
"source_id": 10,
|
||||
"job_id": 99,
|
||||
"start_sec": 0,
|
||||
"end_sec": 60,
|
||||
},
|
||||
)
|
||||
assert resp.status_code == 400
|
||||
assert resp.json()["code"] == "VIDEO_TOO_LARGE"
|
||||
Reference in New Issue
Block a user