diff --git a/tradein-mvp/backend/tests/test_domclick_sweep.py b/tradein-mvp/backend/tests/test_domclick_sweep.py index c0a9bc40..f8733e4a 100644 --- a/tradein-mvp/backend/tests/test_domclick_sweep.py +++ b/tradein-mvp/backend/tests/test_domclick_sweep.py @@ -90,6 +90,41 @@ def test_map_item_basic_mapping() -> None: assert lot.lon == pytest.approx(60.612) +def test_map_item_promotes_rosreestr_from_bff_fixture() -> None: + """isRosreestrApproved из BFF-фикстуры доезжает до + ScrapedLot.is_rosreestr_checked (#3064 п.1). + + На проде у всех 1338 активных domklik-листингов колонка была NULL, хотя поле + уже парсилось и оседало в raw_payload. Соответствие 1:1 с cian + (`offer.get("isRosreestrChecked")`, cian/serp.py:1014) — без трансформаций. + + is_pro_seller здесь НЕ проверяется намеренно: колонка уже несёт два разных + смысла (cian — платная PRO-подписка, `019_listings_alter_cian.sql:43`; + yandex — категория продавца AGENCY/AGENT, `yandex/serp.py:203-220`), и + выводить её из наличия agency_name значило бы завести третий. См. #3064. + """ + import json + from pathlib import Path + + fixture_path = Path(__file__).parent / "fixtures" / "domclick_bff_offers_sample.json" + items = json.loads(fixture_path.read_text(encoding="utf-8"))["result"]["items"] + + config = SimpleNamespace(browser_http_endpoint="http://tradein-browser:9000") + scraper = DomClickScraper(config, delay_provider=lambda _name: 8.0) + + # item 1001: isRosreestrApproved=true -> ЕГРН-сверка пройдена. + lot_checked = scraper._map_item(items[0]) + assert lot_checked is not None + assert lot_checked.is_rosreestr_checked is True + + # item 1003: ключа isRosreestrApproved в payload нет вовсе -> None, а НЕ + # False. Отсутствие данных не то же самое, что "проверено — не сходится": + # False поехал бы в оценщик как утверждение о квартире. + lot_unknown = scraper._map_item(items[2]) + assert lot_unknown is not None + assert lot_unknown.is_rosreestr_checked is None + + # ── fetch_city: report_ban на QRATOR-блок (#2600 п.1) ─────────────────────────── diff --git a/tradein-mvp/packages/scraper-kit/src/scraper_kit/providers/domclick/serp.py b/tradein-mvp/packages/scraper-kit/src/scraper_kit/providers/domclick/serp.py index 9e93cbe1..7f08d272 100644 --- a/tradein-mvp/packages/scraper-kit/src/scraper_kit/providers/domclick/serp.py +++ b/tradein-mvp/packages/scraper-kit/src/scraper_kit/providers/domclick/serp.py @@ -661,6 +661,11 @@ class DomClickScraper(BaseScraper): if not isinstance(seller, dict): seller = {} agency_name = _extract_agency_name(seller) + # ── ЕГРН-проверка (Layer A promote, #3064) ───────────────────────── + # isRosreestrApproved — прямое 1:1 соответствие ScrapedLot.is_rosreestr_checked + # (mirror cian serp.py: offer.get("isRosreestrChecked")). Оставляем ключ и + # в raw_payload (как cian) — совместимость с существующими consumers. + is_rosreestr_checked: bool | None = item.get("isRosreestrApproved") flat_complex = item.get("flatComplex") or {} raw_payload: dict[str, Any] = { @@ -714,6 +719,7 @@ class DomClickScraper(BaseScraper): repair_state=repair_state, description_minhash=description_minhash, agency_name=agency_name, + is_rosreestr_checked=is_rosreestr_checked, raw_payload=raw_payload, ) except Exception: