from __future__ import annotations from pathlib import Path from fastapi import FastAPI from fastapi.testclient import TestClient import pytest from yt_scraper.config import Config from yt_scraper.store import Store, VideoRef from yt_scraper.webapp.api import build_router from yt_scraper.webapp.jobs import JobManager @pytest.fixture def api_client(tmp_path: Path, monkeypatch): db_path = tmp_path / "state.db" md_root = tmp_path / "markdown" md_root.mkdir() store = Store(db_path) cfg = Config(database_path=str(db_path), output_dir=str(md_root)) jobs = JobManager(store, cfg) router = build_router(store, cfg, jobs) app = FastAPI() app.include_router(router) client = TestClient(app) return client, store, cfg, tmp_path def test_get_and_open_markdown(api_client, monkeypatch): client, store, cfg, tmp_path = api_client store.upsert_channel("UC1", "@test", "Test Channel", 1) store.upsert_videos([ VideoRef("vid1", "UC1", "Test Video", "https://www.youtube.com/watch?v=vid1") ]) # 1. Not generated yet -> 404 r_get = client.get("/api/videos/vid1/markdown") assert r_get.status_code == 404 r_open = client.post("/api/videos/vid1/open-markdown") assert r_open.status_code == 404 # 2. Create markdown file and mark done md_dir = tmp_path / "markdown" / "Test Channel" md_dir.mkdir(parents=True) md_file = md_dir / "2026-08-23_test-video.md" md_content = "# Test Video\n\nContent here" md_file.write_text(md_content, encoding="utf-8", newline="\n") rel_path = "markdown/Test Channel/2026-08-23_test-video.md" store.mark_done("vid1", rel_path, "es", "auto", False) # 3. GET markdown returns text r_get = client.get("/api/videos/vid1/markdown") assert r_get.status_code == 200 assert r_get.text.replace("\r\n", "\n") == md_content # 4. POST open-markdown calls _open_in_os opened_paths = [] from yt_scraper.webapp import api as api_mod monkeypatch.setattr(api_mod, "_open_in_os", lambda p: opened_paths.append(str(p))) r_open = client.post("/api/videos/vid1/open-markdown") assert r_open.status_code == 200 assert len(opened_paths) == 1 assert str(md_file.resolve()) in [str(Path(p).resolve()) for p in opened_paths]