Files
omni-parse/tests/test_ingest_quality.py
Vlad Gothbreach c1d2d1bbda
Some checks failed
ci / test (3.10) (push) Has been cancelled
ci / test (3.11) (push) Has been cancelled
ci / test (3.12) (push) Has been cancelled
fix: preserve short release titles and cover source generation contracts
2026-10-27 02:09:37 +03:00

119 lines
5.5 KiB
Python

"""Offline regressions for feed metadata, date ranking and challenge filtering."""
import sys
from datetime import datetime, timezone
from pathlib import Path
from types import SimpleNamespace
import pytest
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
from omni import feeds, rank
from omni.dates import parse_published
from omni.model import Item
from omni.sources import S
@pytest.mark.parametrize("value", [
"2026-10-20T12:00:00Z", "2026-10-20T15:00:00+03:00",
"Tue, 20 Oct 2026 12:00:00 GMT", "2026-10-20T12:00:00",
"1792497600", "1792497600000", 1792497600,
])
def test_publication_formats_have_equal_freshness(value, monkeypatch):
stamp = datetime(2026, 10, 20, 12, tzinfo=timezone.utc).timestamp()
parsed = parse_published(value)
assert parsed is not None
assert parsed.timestamp() == stamp
monkeypatch.setattr(rank.time, "time", lambda: stamp + 86400)
assert rank._fresh(value) == pytest.approx(1 - 1 / 30)
def test_date_only_and_invalid_dates(monkeypatch):
stamp = datetime(2026, 10, 20, tzinfo=timezone.utc).timestamp()
monkeypatch.setattr(rank.time, "time", lambda: stamp)
assert rank._fresh("2026-10-20") == 1
for value in (None, "", "not a date", "99999999999999999999999999", "NaN"):
assert parse_published(value) is None
assert rank._fresh(value) == 0.3
assert rank._fresh("2020-01-01") == 0
assert parse_published("2026") is None
assert parse_published("20261020") == datetime(2026, 10, 20, tzinfo=timezone.utc)
def test_atom_alternate_links_author_and_date(monkeypatch):
src = S("atom_test", "models", "rss", "https://example.invalid/feed.atom")
xml = '''<feed xmlns="http://www.w3.org/2005/Atom"><entry>
<title>Runtime release 2.0</title>
<link rel="self" href="https://example.invalid/api/123"/>
<link rel="alternate" href="/releases/2.0"/>
<author><name>Release team</name></author>
<published>2026-10-20T15:00:00+03:00</published>
<summary>Faster inference and improved caching.</summary>
</entry></feed>'''
monkeypatch.setattr(feeds.net, "get", lambda *a, **kw: SimpleNamespace(status=200, text=xml))
rows = feeds.fetch(src)
assert len(rows) == 1
assert rows[0].url == "https://example.invalid/releases/2.0"
assert rows[0].author == "Release team"
assert rows[0].published == "2026-10-20T12:00:00+00:00"
def test_rss_namespaced_creator_and_no_author(monkeypatch):
src = S("rss_test", "security", "rss", "https://example.invalid/feed")
xml = '''<rss xmlns:dc="http://purl.org/dc/elements/1.1/"><channel>
<item><title>Security advisory</title><link>https://example.invalid/advisory</link>
<dc:creator>Security team</dc:creator><pubDate>Tue, 20 Oct 2026 12:00:00 GMT</pubDate></item>
<item><title>New patch available</title><link>https://example.invalid/patch</link></item>
</channel></rss>'''
monkeypatch.setattr(feeds.net, "get", lambda *a, **kw: SimpleNamespace(status=200, text=xml))
rows = feeds.fetch(src)
assert len(rows) == 2
assert rows[0].author == "Security team"
assert rows[0].published == "2026-10-20T12:00:00+00:00"
assert rows[1].author == ""
def test_fetch_drops_invalid_pages_but_keeps_short_real_posts(monkeypatch):
src = S("test", "security", "rss", "https://example.invalid/feed", "test_adapter")
def item(path, title, text=""):
return Item("test", "entry", url=path, title=title, text=text)
good = item("https://example.invalid/release", "v1.2")
real = item("https://example.invalid/article", "Access denied", "Real analysis of authorization failure. " * 20)
rows = [
item("", "A missing URL"),
item("javascript:alert(1)", "A dangerous URL"),
item("https://example.invalid/blank", ""),
item("https://example.invalid/challenge", "Just a moment...", "Checking your browser"),
item("https://example.invalid/denied", "Attention Required! | Cloudflare", "captcha"),
item("https://example.invalid/long-challenge", "Just a moment...",
"Checking your browser before accessing this site. " * 20),
{"title": "Malformed adapter result"}, None, "not an Item",
good, item(good.url, "Duplicate record"), real,
]
monkeypatch.setitem(feeds.ADAPTERS, "test_adapter", lambda source, n: rows)
assert feeds.fetch(src) == [good, real]
def test_fetch_bad_record_does_not_discard_valid_siblings(monkeypatch):
src = S("test", "security", "rss", "https://example.invalid/feed", "test_adapter")
good = Item("test", "entry", url="https://example.invalid/release", title="Real release")
bad = Item("test", "entry", url="https://example.invalid/bad", title="Malformed")
bad.text = None
monkeypatch.setitem(feeds.ADAPTERS, "test_adapter", lambda source, n: [bad, good])
assert feeds.fetch(src) == [good]
@pytest.mark.parametrize("title", ["GPT-5 launched", "Release 2.0", "v2.1.0"])
def test_feed_keeps_short_release_titles(title):
src = S("release_test", "models", "atom", "https://example.invalid/feed")
row = feeds._item(src, "entry", "https://example.invalid/release", title,
"Long description that must not replace the release title.")
assert row.title == title
def test_telegram_still_uses_body_for_empty_heading():
src = S("tg_test", "security", "tg", "https://t.me/s/example", "tg_web")
body = "An advisory with a meaningful first line."
row = feeds._item(src, "post", "https://t.me/example/1", "...", body)
assert row.title == body