parser: ETag/304-кэш, 61 авто-источник из 81 кандидата (+RSS AI/security), правила farm/weights, тесты sources_auto
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

This commit is contained in:
Vlad Gothbreach
2026-10-27 20:34:52 +03:00
parent 31a8dd8c4d
commit d6ad507d7e
6 changed files with 233 additions and 22 deletions

View File

@@ -0,0 +1,53 @@
"""Санити-тесты авто-реестра источников (без сети).
Проверяют, что сгенерированный `omni/sources_auto.py` не битый: адаптеры существуют,
имена/url не дублируются, обязательные поля на месте. Сами фиды тут не дергаются —
живость проверяет `tools/auto_expand.py --probe`.
"""
from __future__ import annotations
import re
import pytest
from omni import feeds, sources
from omni.sources_auto import AUTO
def test_auto_not_empty():
assert AUTO, "sources_auto.py пустой — прогони tools/auto_expand.py --probe --write"
@pytest.mark.parametrize("entry", AUTO, ids=[d.get("name", "?") for d in AUTO])
def test_entry_shape(entry):
for key in ("name", "url", "adapter", "kind"):
assert entry.get(key), "у записи нет поля %s: %r" % (key, entry)
assert entry["url"].startswith("http"), entry["url"]
assert entry["adapter"] in feeds.ADAPTERS, "неизвестный адаптер: %s" % entry["adapter"]
assert entry.get("category", "abuse") == "abuse"
def test_names_and_urls_unique():
names = [d["name"] for d in AUTO]
urls = [d["url"] for d in AUTO]
assert len(names) == len(set(names)), "дубли имён в AUTO"
assert len(urls) == len(set(urls)), "дубли url в AUTO"
def test_all_auto_registered_in_sources():
"""Каждая живая запись должна попасть в общий реестр (или быть схлопнутой дедупом по url)."""
registered = {s.name for s in sources.SOURCES if s.name.startswith("aa_")}
existing_urls = {s.url for s in sources.SOURCES}
missing = [d["name"] for d in AUTO if d["name"] not in registered and d["url"] not in existing_urls]
assert not missing, "не попали в SOURCES: %s" % missing[:5]
def test_generated_file_is_marked_generated():
from pathlib import Path
import omni
path = Path(omni.__file__).parent / "sources_auto.py"
head = path.read_text(encoding="utf-8")[:400]
assert "генерируется" in head, "шапка файла должна предупреждать, что он генерируется"
assert re.search(r"AUTO = \[", path.read_text(encoding="utf-8")), "нет списка AUTO"