from __future__ import annotations import tempfile import unittest from pathlib import Path from biliup_next.core.models import SessionBinding, Task, TaskContext, TaskStep from biliup_next.infra.db import Database from biliup_next.infra.task_repository import TaskRepository class TaskRepositorySqliteTests(unittest.TestCase): def setUp(self) -> None: self.tempdir = tempfile.TemporaryDirectory() db_path = Path(self.tempdir.name) / "test.db" self.db = Database(db_path) self.db.initialize() self.repo = TaskRepository(self.db) def tearDown(self) -> None: self.tempdir.cleanup() def test_query_tasks_filters_and_sorts_by_updated_desc(self) -> None: self.repo.upsert_task(Task("task-1", "local_file", "/tmp/a.mp4", "Alpha", "created", "2026-01-01T00:00:00+00:00", "2026-01-01T00:01:00+00:00")) self.repo.upsert_task(Task("task-2", "local_file", "/tmp/b.mp4", "Beta", "published", "2026-01-01T00:00:00+00:00", "2026-01-01T00:03:00+00:00")) self.repo.upsert_task(Task("task-3", "local_file", "/tmp/c.mp4", "Gamma", "published", "2026-01-01T00:00:00+00:00", "2026-01-01T00:02:00+00:00")) items, total = self.repo.query_tasks(status="published", search="a", sort="updated_desc") self.assertEqual(total, 2) self.assertEqual([item.id for item in items], ["task-2", "task-3"]) def test_list_task_contexts_and_steps_for_task_ids_returns_batched_maps(self) -> None: self.repo.upsert_task(Task("task-1", "local_file", "/tmp/a.mp4", "Alpha", "created", "2026-01-01T00:00:00+00:00", "2026-01-01T00:01:00+00:00")) self.repo.upsert_task(Task("task-2", "local_file", "/tmp/b.mp4", "Beta", "created", "2026-01-01T00:00:00+00:00", "2026-01-01T00:02:00+00:00")) self.repo.upsert_task_context( TaskContext( id=None, task_id="task-1", session_key="session-1", streamer="streamer", room_id="room", source_title="Alpha", segment_started_at="2026-01-01T00:00:00+00:00", segment_duration_seconds=60.0, full_video_bvid="BV123", created_at="2026-01-01T00:00:00+00:00", updated_at="2026-01-01T00:00:00+00:00", ) ) self.repo.replace_steps( "task-1", [ TaskStep(None, "task-1", "transcribe", "pending", None, None, 0, None, None), TaskStep(None, "task-1", "song_detect", "pending", None, None, 0, None, None), ], ) self.repo.replace_steps( "task-2", [ TaskStep(None, "task-2", "transcribe", "running", None, None, 0, "2026-01-01T00:03:00+00:00", None), ], ) contexts = self.repo.list_task_contexts_for_task_ids(["task-1", "task-2"]) steps = self.repo.list_steps_for_task_ids(["task-1", "task-2"]) self.assertEqual(set(contexts.keys()), {"task-1"}) self.assertEqual(contexts["task-1"].full_video_bvid, "BV123") self.assertEqual([step.step_name for step in steps["task-1"]], ["transcribe", "song_detect"]) self.assertEqual(steps["task-2"][0].status, "running") def test_session_binding_supports_upsert_and_source_title_fallback_lookup(self) -> None: self.repo.upsert_session_binding( SessionBinding( id=None, session_key="session-1", source_title="Alpha", streamer="streamer", room_id="room", full_video_bvid="BVOLD", created_at="2026-01-01T00:00:00+00:00", updated_at="2026-01-01T00:00:00+00:00", ) ) self.repo.upsert_session_binding( SessionBinding( id=None, session_key="session-1", source_title="Alpha", streamer="streamer", room_id="room", full_video_bvid="BVNEW", created_at="2026-01-01T00:01:00+00:00", updated_at="2026-01-01T00:01:00+00:00", ) ) self.repo.upsert_session_binding( SessionBinding( id=None, session_key=None, source_title="Beta", streamer="streamer-2", room_id="room-2", full_video_bvid="BVBETA", created_at="2026-01-01T00:02:00+00:00", updated_at="2026-01-01T00:02:00+00:00", ) ) binding_by_session = self.repo.get_session_binding(session_key="session-1") binding_by_title = self.repo.get_session_binding(source_title="Beta") self.assertIsNotNone(binding_by_session) self.assertEqual(binding_by_session.full_video_bvid, "BVNEW") self.assertIsNotNone(binding_by_title) self.assertEqual(binding_by_title.full_video_bvid, "BVBETA") if __name__ == "__main__": unittest.main()