"""Tests for video detail and transcript endpoints. Covers: - GET /api/v1/videos/{video_id} — single video with creator info - GET /api/v1/videos/{video_id}/transcript — ordered segments """ import uuid import pytest import pytest_asyncio from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker from models import ContentType, Creator, ProcessingStatus, SourceVideo, TranscriptSegment @pytest_asyncio.fixture() async def video_with_creator(db_engine): """Create a Creator + SourceVideo pair. Returns dict with IDs.""" factory = async_sessionmaker(db_engine, class_=AsyncSession, expire_on_commit=False) async with factory() as session: creator = Creator( name="TestProducer", slug="testproducer", folder_name="TestProducer", genres=["electronic"], ) session.add(creator) await session.flush() video = SourceVideo( creator_id=creator.id, filename="synth-tutorial.mp4", file_path="TestProducer/synth-tutorial.mp4", duration_seconds=720, content_type=ContentType.tutorial, processing_status=ProcessingStatus.complete, ) session.add(video) await session.flush() result = { "creator_id": creator.id, "creator_name": creator.name, "creator_slug": creator.slug, "video_id": video.id, } await session.commit() return result @pytest_asyncio.fixture() async def video_with_segments(db_engine, video_with_creator): """Add transcript segments to the video. Returns video_with_creator + segment count.""" factory = async_sessionmaker(db_engine, class_=AsyncSession, expire_on_commit=False) async with factory() as session: segments = [ TranscriptSegment( source_video_id=video_with_creator["video_id"], start_time=float(i * 10), end_time=float(i * 10 + 9), text=f"Segment {i} text content.", segment_index=i, ) for i in range(5) ] session.add_all(segments) await session.commit() return {**video_with_creator, "segment_count": 5} # ── Video Detail ───────────────────────────────────────────────────────────── @pytest.mark.asyncio async def test_get_video_detail_success(client, video_with_creator): vid = video_with_creator["video_id"] resp = await client.get(f"/api/v1/videos/{vid}") assert resp.status_code == 200 data = resp.json() assert data["id"] == str(vid) assert data["filename"] == "synth-tutorial.mp4" assert data["creator_name"] == "TestProducer" assert data["creator_slug"] == "testproducer" # video_url is always None for now assert data["video_url"] is None @pytest.mark.asyncio async def test_get_video_detail_404(client): fake_id = uuid.uuid4() resp = await client.get(f"/api/v1/videos/{fake_id}") assert resp.status_code == 404 assert "not found" in resp.json()["detail"].lower() # ── Transcript ─────────────────────────────────────────────────────────────── @pytest.mark.asyncio async def test_get_transcript_success(client, video_with_segments): vid = video_with_segments["video_id"] resp = await client.get(f"/api/v1/videos/{vid}/transcript") assert resp.status_code == 200 data = resp.json() assert data["video_id"] == str(vid) assert data["total"] == 5 assert len(data["segments"]) == 5 # Verify ordering by segment_index indices = [s["segment_index"] for s in data["segments"]] assert indices == [0, 1, 2, 3, 4] @pytest.mark.asyncio async def test_get_transcript_404(client): fake_id = uuid.uuid4() resp = await client.get(f"/api/v1/videos/{fake_id}/transcript") assert resp.status_code == 404 @pytest.mark.asyncio async def test_get_transcript_empty(client, video_with_creator): """Video exists but has no segments — returns empty list.""" vid = video_with_creator["video_id"] resp = await client.get(f"/api/v1/videos/{vid}/transcript") assert resp.status_code == 200 data = resp.json() assert data["video_id"] == str(vid) assert data["total"] == 0 assert data["segments"] == []