"""Discovery: feed parsing, the API backfill, and duration enrichment.""" from __future__ import annotations from datetime import date, timedelta import pytest from ytstream import api, discovery, util, videos from conftest import FakeApi, add_video, make_feed, patch_api def _entry(video_id, published, title="A video"): return {"video_id": video_id, "published": published, "title": title} @pytest.fixture() def offline(monkeypatch): """No feed fetches and no API calls unless a test asks for them.""" monkeypatch.setattr(discovery, "fetch_feed", lambda *a, **k: pytest.fail("unexpected feed fetch")) patch_api(monkeypatch, discovery, FakeApi()) # --------------------------------------------------------------- feed parsing def test_parse_entries_reads_only_atom_entries(): """The feed-level is the playlist's creation date, sometimes years old. Treating it as a video produced a nonsense 0.01/day upload rate once.""" payload = make_feed( [_entry("vid00000001", "2026-08-11T10:00:00+00:00")], playlist_published="2019-03-01T00:00:00+00:00", ) entries = discovery.parse_entries(payload) assert len(entries) == 1 assert entries[0]["published"] == date(2026, 8, 11) def test_parse_entries_keeps_the_exact_timestamp(): payload = make_feed([_entry("vid00000001", "2026-08-11T16:32:10+00:00")]) assert discovery.parse_entries(payload)[0]["published_at"].startswith( "2026-08-11T16:32:10" ) def test_parse_entries_skips_undated_entries(): payload = make_feed([_entry("vid00000001", "not-a-date"), _entry("vid00000002", "2026-08-11T10:00:00+00:00")]) assert [e["video_id"] for e in discovery.parse_entries(payload)] == ["vid00000002"] def test_parse_entries_rejects_garbage(): with pytest.raises(discovery.FeedUnavailable): discovery.parse_entries(b"