"""Smoke-proof для parity-harness'а (tests/support/parity.py) — issue #2304. Доказывает, что harness реально ловит эквивалентность legacy ↔ scraper_kit на РЕАЛЬНОЙ паре функций, а не на синтетике: `parse_detail_html` — parsing-ядро, которое `app/api/v1/admin.py::scrape_avito_detail` (debug-роут ручного запуска парсера) вызывает косвенно через `fetch_detail()` (fetch_detail = HTTP GET + `parse_detail_html(html, url)`; сам parse — чистая функция, без сети/БД, что и позволяет сравнить её offline на фиксированной HTML-фикстуре). `app/services/scrapers/avito_detail.py::parse_detail_html` (legacy) и `scraper_kit/providers/avito/detail.py::parse_detail_html` (kit) на момент написания теста ИДЕНТИЧНЫ по телу функции (см. audit `Scraper_Kit_Legacy_Dependency_Audit_0703` в vault) — различаются только import-пути модулей, из которых берутся зависимости (`app.services.scrapers.*` vs `scraper_kit.*`) и Strangler-инжекция `ScraperConfig` в соседних функциях (`fetch_detail`, `_build_detail_session`), которую сам `parse_detail_html` не использует. Это НЕ миграция admin.py (issue #2305+) — только доказательство инструмента. HTML-фикстура — тот же minimal-marker набор, что и в `tests/test_avito_detail_parse.py::test_minimal_parse` (независимая копия литерала, чтобы этот тест не зависел от другого test-модуля). """ # ruff: noqa: E501 # HTML-фикстура содержит длинные строки разметки from __future__ import annotations import dataclasses import os # app.services.scrapers.avito_detail импортирует app.core.config.settings=Settings(), # которому нужен DATABASE_URL. Офлайн-парсинг БД не трогает — фиктивный DSN достаточен # (mirror tests/test_scraper_kit_avito_golden_parity.py — тест должен жить и без # CI-уровневого DATABASE_URL из ci-tradein.yml/deploy-tradein.yml). os.environ.setdefault("DATABASE_URL", "postgresql+psycopg://test:test@localhost/test_db") from scraper_kit.providers.avito.detail import ( parse_detail_html as kit_parse_detail_html, ) from app.services.scrapers.avito_detail import ( parse_detail_html as legacy_parse_detail_html, ) from tests.support.parity import assert_parity _DETAIL_HTML = """
1 собственник
Последняя смена собственника 5 мая 2020
Не найдены ограничения и обременения
Совпадают площадь, адрес и этаж