Download dashboard/tests/test_db.py from afluakd9/Video-downloader-CPU-basic: direct link, hf CLI and curl.
- Browser
- Download file 8.76 kB
-
https://huggingface.co/spaces/afluakd9/Video-downloader-CPU-basic/resolve/main/dashboard/tests/test_db.py
- Command line
-
hf download hf://spaces/afluakd9/Video-downloader-CPU-basic/dashboard/tests/test_db.py
-
curl -L -o test_db.py https://huggingface.co/spaces/afluakd9/Video-downloader-CPU-basic/resolve/main/dashboard/tests/test_db.py
8.76 kB
| """Tests for dashboard/db.py""" | |
| import asyncio | |
| import os | |
| import tempfile | |
| import time | |
| # Must set DB_PATH before importing db | |
| _tmpdir = tempfile.mkdtemp() | |
| os.environ["DB_PATH"] = os.path.join(_tmpdir, "test_reclip.db") | |
| import db # noqa: E402 | |
| _loop = asyncio.new_event_loop() | |
| def run(coro): | |
| return _loop.run_until_complete(coro) | |
| # --------------------------------------------------------------------------- | |
| # Helpers | |
| # --------------------------------------------------------------------------- | |
| def _job(suffix=""): | |
| return f"job-{suffix or int(time.time() * 1000)}" | |
| async def _seed_download(job_id, platform="youtube", status="done", user_id=1, | |
| username="alice", chat_id=100, url="https://example.com/v"): | |
| await db.insert_download_start( | |
| job_id=job_id, user_id=user_id, username=username, | |
| chat_id=chat_id, url=url, platform=platform, | |
| ) | |
| if status == "done": | |
| await db.update_download_done( | |
| job_id=job_id, title="Test Video", format="mp4", | |
| quality="720p", file_size_bytes=1_000_000, | |
| download_duration_sec=3.5, | |
| ) | |
| elif status == "error": | |
| await db.update_download_error(job_id=job_id, error_message="network timeout") | |
| # --------------------------------------------------------------------------- | |
| # Task 1 tests: CRUD | |
| # --------------------------------------------------------------------------- | |
| def test_insert_download_start(): | |
| job_id = _job("start1") | |
| run(db.insert_download_start( | |
| job_id=job_id, user_id=42, username="bob", | |
| chat_id=999, url="https://youtube.com/watch?v=abc", | |
| platform="youtube", | |
| )) | |
| row = run(db.get_download_by_job_id(job_id)) | |
| assert row is not None | |
| assert row["job_id"] == job_id | |
| assert row["status"] == "started" | |
| assert row["user_id"] == 42 | |
| assert row["username"] == "bob" | |
| assert row["platform"] == "youtube" | |
| assert row["url"] == "https://youtube.com/watch?v=abc" | |
| def test_update_download_done(): | |
| job_id = _job("done1") | |
| run(db.insert_download_start( | |
| job_id=job_id, user_id=1, username="alice", | |
| chat_id=10, url="https://example.com", | |
| platform="tiktok", | |
| )) | |
| run(db.update_download_done( | |
| job_id=job_id, title="Cool Clip", format="mp4", | |
| quality="1080p", file_size_bytes=5_000_000, | |
| download_duration_sec=10.2, | |
| )) | |
| row = run(db.get_download_by_job_id(job_id)) | |
| assert row["status"] == "done" | |
| assert row["title"] == "Cool Clip" | |
| assert row["format"] == "mp4" | |
| assert row["quality"] == "1080p" | |
| assert row["file_size_bytes"] == 5_000_000 | |
| assert abs(row["download_duration_sec"] - 10.2) < 0.01 | |
| assert row["completed_at"] is not None | |
| def test_update_download_error(): | |
| job_id = _job("err1") | |
| run(db.insert_download_start( | |
| job_id=job_id, user_id=7, username="charlie", | |
| chat_id=77, url="https://example.com", | |
| platform="instagram", | |
| )) | |
| run(db.update_download_error(job_id=job_id, error_message="403 Forbidden")) | |
| row = run(db.get_download_by_job_id(job_id)) | |
| assert row["status"] == "error" | |
| assert row["error_message"] == "403 Forbidden" | |
| assert row["completed_at"] is not None | |
| def test_get_download_by_job_id_missing(): | |
| row = run(db.get_download_by_job_id("nonexistent-job-id")) | |
| assert row is None | |
| # --------------------------------------------------------------------------- | |
| # Task 2 tests: stats queries | |
| # --------------------------------------------------------------------------- | |
| def test_get_dashboard_stats_empty(): | |
| """Stats on a fresh DB (after inserts above, but we want structure check).""" | |
| stats = run(db.get_dashboard_stats()) | |
| assert "downloads_today" in stats | |
| assert "downloads_yesterday" in stats | |
| assert "active_users_24h" in stats | |
| assert "error_rate" in stats | |
| assert "error_rate_yesterday" in stats | |
| assert "errors_today" in stats | |
| assert "total_today" in stats | |
| def test_get_dashboard_stats_with_data(): | |
| job_done = _job("stats-done") | |
| job_err = _job("stats-err") | |
| run(_seed_download(job_done, platform="youtube", status="done")) | |
| run(_seed_download(job_err, platform="youtube", status="error")) | |
| stats = run(db.get_dashboard_stats()) | |
| # At least the downloads we inserted are counted | |
| assert stats["downloads_today"] >= 1 | |
| assert stats["errors_today"] >= 1 | |
| assert stats["total_today"] >= 2 | |
| def test_get_chart_data_ranges(): | |
| for rng in ("1D", "7D", "1M", "1Y"): | |
| data = run(db.get_chart_data(rng)) | |
| assert "labels" in data | |
| assert "values" in data | |
| assert "platforms" in data | |
| assert "top_users" in data | |
| assert isinstance(data["labels"], list) | |
| assert isinstance(data["values"], list) | |
| assert isinstance(data["platforms"], list) | |
| assert isinstance(data["top_users"], list) | |
| assert len(data["labels"]) == len(data["values"]) | |
| def test_get_chart_data_platform_top5(): | |
| data = run(db.get_chart_data("7D")) | |
| assert len(data["platforms"]) <= 5 | |
| for p in data["platforms"]: | |
| assert "platform" in p | |
| assert "count" in p | |
| def test_get_chart_data_top_users(): | |
| data = run(db.get_chart_data("7D")) | |
| assert len(data["top_users"]) <= 5 | |
| for u in data["top_users"]: | |
| assert "username" in u | |
| assert "count" in u | |
| def test_get_downloads_page_basic(): | |
| result = run(db.get_downloads_page(page=1, per_page=10)) | |
| assert "rows" in result | |
| assert "total" in result | |
| assert "pages" in result | |
| assert "page" in result | |
| assert result["page"] == 1 | |
| assert isinstance(result["rows"], list) | |
| def test_get_downloads_page_pagination(): | |
| # Seed 5 more downloads | |
| for i in range(5): | |
| run(_seed_download(_job(f"page-{i}"), platform="youtube", status="done", | |
| user_id=10 + i, username=f"user{i}")) | |
| result_p1 = run(db.get_downloads_page(page=1, per_page=3)) | |
| assert len(result_p1["rows"]) == 3 | |
| assert result_p1["total"] >= 5 | |
| result_p2 = run(db.get_downloads_page(page=2, per_page=3)) | |
| assert len(result_p2["rows"]) >= 1 | |
| # No overlap between pages | |
| ids_p1 = {r["id"] for r in result_p1["rows"]} | |
| ids_p2 = {r["id"] for r in result_p2["rows"]} | |
| assert ids_p1.isdisjoint(ids_p2) | |
| def test_get_downloads_page_filters(): | |
| run(_seed_download(_job("filter-tw"), platform="twitter", status="done", | |
| user_id=999, username="twitteruser")) | |
| result = run(db.get_downloads_page(page=1, per_page=50, platform="twitter")) | |
| assert all(r["platform"] == "twitter" for r in result["rows"]) | |
| result_err = run(db.get_downloads_page(page=1, per_page=50, status="error")) | |
| assert all(r["status"] == "error" for r in result_err["rows"]) | |
| result_user = run(db.get_downloads_page(page=1, per_page=50, user="twitteruser")) | |
| assert any(r["username"] == "twitteruser" for r in result_user["rows"]) | |
| def test_get_error_downloads(): | |
| errors = run(db.get_error_downloads()) | |
| assert isinstance(errors, list) | |
| for e in errors: | |
| assert e["status"] == "error" | |
| def test_get_error_downloads_date_filter(): | |
| from datetime import datetime, timezone, timedelta | |
| yesterday = (datetime.now(timezone.utc) - timedelta(days=1)).strftime("%Y-%m-%d") | |
| tomorrow = (datetime.now(timezone.utc) + timedelta(days=1)).strftime("%Y-%m-%d") | |
| errors = run(db.get_error_downloads(date_from=yesterday, date_to=tomorrow)) | |
| assert isinstance(errors, list) | |
| # All errors we seeded today should appear | |
| for e in errors: | |
| assert e["status"] == "error" | |
| def test_insert_and_get_disk_snapshot(): | |
| run(db.insert_disk_snapshot(total_bytes=1_000_000_000, file_count=42)) | |
| snap = run(db.get_latest_disk_snapshot()) | |
| assert snap is not None | |
| assert snap["total_bytes"] == 1_000_000_000 | |
| assert snap["file_count"] == 42 | |
| assert snap["snapshot_at"] is not None | |
| def test_get_latest_disk_snapshot_empty(): | |
| # Use a separate temp DB to test empty state | |
| with tempfile.TemporaryDirectory() as d: | |
| old_path = os.environ["DB_PATH"] | |
| empty_path = os.path.join(d, "empty.db") | |
| os.environ["DB_PATH"] = empty_path | |
| # init_db will create schema on empty_path | |
| run(db.init_db()) | |
| snap = run(db.get_latest_disk_snapshot()) | |
| assert snap is None | |
| os.environ["DB_PATH"] = old_path | |
| def test_disk_snapshot_latest_is_newest(): | |
| run(db.insert_disk_snapshot(total_bytes=100, file_count=1)) | |
| run(db.insert_disk_snapshot(total_bytes=200, file_count=2)) | |
| run(db.insert_disk_snapshot(total_bytes=300, file_count=3)) | |
| snap = run(db.get_latest_disk_snapshot()) | |
| assert snap["total_bytes"] == 300 | |
| assert snap["file_count"] == 3 | |