Files
daily-robots/tests/test_rss_parse.py
2026-07-03 16:39:11 +08:00

97 lines
2.8 KiB
Python

from __future__ import annotations
from pathlib import Path
import pytest
FIXTURES = Path(__file__).parent / "fixtures"
def test_parse_sample_rss_fixture():
from daily.news.feeds import NEWS_CATEGORIES
from daily.news.fetch import _parse_feed
category = NEWS_CATEGORIES[0]
feed_name = category.feeds[0].name
xml = (FIXTURES / "sample-rss.xml").read_text(encoding="utf-8")
items = _parse_feed(xml, feed_name, category)
assert len(items) == 1
assert items[0]["title"] == "Sample AI headline for smoke tests"
assert items[0]["link"] == "https://example.com/ai-news/1"
assert items[0]["source_name"] == feed_name
assert "minimal RSS item" in items[0]["summary"]
def test_rss_user_agent_avoids_bot_blocked_feeds():
from daily.news.fetch import RSS_USER_AGENT
assert "daily-robots" not in RSS_USER_AGENT
def test_fetch_one_retries_transient_errors(monkeypatch):
import httpx
from daily.news.feeds import NEWS_CATEGORIES
from daily.news import fetch as news_fetch
monkeypatch.setenv("DAILY_RSS_RETRY", "2")
monkeypatch.setattr(news_fetch.time, "sleep", lambda _: None)
category = NEWS_CATEGORIES[0]
feed = category.feeds[0]
calls = {"n": 0}
class FakeResponse:
def raise_for_status(self):
return None
@property
def text(self):
return (FIXTURES / "sample-rss.xml").read_text(encoding="utf-8")
class FakeClient:
headers = {"User-Agent": "test"}
def get(self, url, headers=None):
calls["n"] += 1
if calls["n"] < 2:
raise httpx.RemoteProtocolError("Server disconnected")
return FakeResponse()
entries, ok = news_fetch._fetch_one(FakeClient(), category, feed)
assert ok is True
assert len(entries) == 1
assert calls["n"] == 2
def test_fetch_ai_news_offline(monkeypatch):
from daily.news import fetch as news_fetch
sample = {
"title": "Sample AI headline for smoke tests",
"link": "https://example.com/ai-news/1",
"summary": "A minimal RSS item used by offline tests.",
"published": "Wed, 02 Jul 2026 08:00:00 GMT",
"source_name": "OpenAI",
"category_id": "official",
"category_name": "厂商官方",
"category_icon": "🏢",
}
monkeypatch.setattr(
news_fetch,
"_fetch_news",
lambda categories: {
"enabled": True,
"hours": 72,
"categories": [{"id": "official", "name": "厂商官方", "icon": "🏢", "items": [sample]}],
"flat": [sample],
"stats": {"feeds_total": 1, "feeds_ok": 1, "items_raw": 1, "feeds_failed": []},
},
)
payload = news_fetch.fetch_ai_news()
assert payload["enabled"] is True
assert payload["flat"][0]["title"].startswith("Sample AI")