feat(tradein/domklik): пробросить isRosreestrApproved в колонку #3068
2 changed files with 41 additions and 0 deletions
|
|
@ -90,6 +90,41 @@ def test_map_item_basic_mapping() -> None:
|
||||||
assert lot.lon == pytest.approx(60.612)
|
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) ───────────────────────────
|
# ── fetch_city: report_ban на QRATOR-блок (#2600 п.1) ───────────────────────────
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -661,6 +661,11 @@ class DomClickScraper(BaseScraper):
|
||||||
if not isinstance(seller, dict):
|
if not isinstance(seller, dict):
|
||||||
seller = {}
|
seller = {}
|
||||||
agency_name = _extract_agency_name(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 {}
|
flat_complex = item.get("flatComplex") or {}
|
||||||
raw_payload: dict[str, Any] = {
|
raw_payload: dict[str, Any] = {
|
||||||
|
|
@ -714,6 +719,7 @@ class DomClickScraper(BaseScraper):
|
||||||
repair_state=repair_state,
|
repair_state=repair_state,
|
||||||
description_minhash=description_minhash,
|
description_minhash=description_minhash,
|
||||||
agency_name=agency_name,
|
agency_name=agency_name,
|
||||||
|
is_rosreestr_checked=is_rosreestr_checked,
|
||||||
raw_payload=raw_payload,
|
raw_payload=raw_payload,
|
||||||
)
|
)
|
||||||
except Exception:
|
except Exception:
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue