"""Tests for /api/stats router (cache, async scan).""" from __future__ import annotations import asyncio import pytest from fastapi.testclient import TestClient from src.web import deps from src.web.app import app from src.web.routers import stats as stats_router @pytest.fixture def client(tmp_path, monkeypatch): downloads = tmp_path / "downloads" downloads.mkdir() monkeypatch.setattr(deps, "DOWNLOADS_DIR", downloads) monkeypatch.setattr(stats_router, "DOWNLOADS_DIR", downloads) stats_router._reset_stats_cache() monkeypatch.setenv("RMC_DB_PATH", str(tmp_path / "media.db")) return TestClient(app) def test_stats_endpoint_returns_expected_keys(client): response = client.get("/api/stats") assert response.status_code == 200 data = response.json() for key in ("file_count", "disk_size_bytes", "disk_size_mb", "disk_size_gb", "disk_free_gb"): assert key in data def test_stats_counts_files_excluding_json(client, tmp_path): # Create some media + a sidecar downloads = tmp_path / "downloads" (downloads / "a.jpg").write_bytes(b"x" * 100) (downloads / "b.mp4").write_bytes(b"y" * 200) (downloads / "a.jpg.json").write_bytes(b"{}") # sidecar should not count stats_router._reset_stats_cache() response = client.get("/api/stats") data = response.json() assert data["file_count"] == 2 assert data["disk_size_bytes"] == 300 def test_stats_cache_serves_stale_within_ttl(client, tmp_path): downloads = tmp_path / "downloads" (downloads / "a.jpg").write_bytes(b"x" * 100) stats_router._reset_stats_cache() first = client.get("/api/stats").json() assert first["file_count"] == 1 # Add another file but don't reset cache; expect cached value (downloads / "b.jpg").write_bytes(b"y" * 50) second = client.get("/api/stats").json() assert second["file_count"] == 1 # cached # After cache reset, the new file is reflected stats_router._reset_stats_cache() third = client.get("/api/stats").json() assert third["file_count"] == 2 def test_scan_downloads_handles_missing_dir(tmp_path): stats_router._reset_stats_cache() missing = tmp_path / "nope" size, count = asyncio.run(stats_router._scan_downloads_cached(missing)) assert size == 0 assert count == 0