financial_estimate (эпик #1881) фаерит только при разрезолвленном НСПД-регламенте (max_far), а он резолвится ЛЕНИВО при анализе участка → zone_regulation_cache всего 33 зоны → у большинства участков financial_estimate=None («—» в кокпите). Backfill проактивно кэширует ВСЕ террзоны ЕКБ (~100-120) → ЛЮБОй участок в известной зоне сразу получает регламент и финмодель. - backfill_ekb_zone_regulations (zone_regulation.py): WFS-перечисление террзон ЕКБ (features_in_bbox 'territorial_zone') → dedup по urban_index (предпочёт фичу с геометрией) → representative_point (внутри полигона, не centroid) → zone_regulation_at → upsert. ИДЕМПОТЕНТНО (cached skip перед fetch), per-zone try/except (один сбой не рушит batch), rate_delay вежливость к геопорталу, limit для частичного прогона. - Celery task backfill_zone_regulations + регистрация в celery_app include + admin POST /api/v1/admin/scrape/zone-regulations/backfill (паттерн objective sync-our). - Ленивый refresh_zone_regulations / get_or_fetch / upsert НЕ тронуты (additive путь). - +9 тестов (dedup, idempotency cached-skip, per-zone error isolation, centroid-inside, limit). mypy/ruff clean. Прод-прогон backfill — отдельный шаг после deploy (как Objective sync), не на deploy. Code-review поймал незарегистрированный task (был бы NotRegistered) — исправлено. Refs #1881
49 lines
1.6 KiB
Python
49 lines
1.6 KiB
Python
"""Тест Celery-таски backfill_zone_regulations (эпик #1881).
|
|
|
|
Сеть/БД не дёргаются: мокаем SessionLocal + backfill_ekb_zone_regulations (логика backfill
|
|
покрыта tests/services/test_zone_regulation_backfill). Проверяем что таска открывает/закрывает
|
|
сессию, прокидывает limit/rate_delay_s и возвращает результат сервиса.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
|
|
from app.workers.tasks import backfill_zone_regulations as task_mod
|
|
|
|
|
|
class _DB:
|
|
def __init__(self) -> None:
|
|
self.closed = False
|
|
|
|
def close(self) -> None:
|
|
self.closed = True
|
|
|
|
|
|
def test_task_wires_args_and_closes_session(monkeypatch: Any) -> None:
|
|
db = _DB()
|
|
captured: dict[str, Any] = {}
|
|
|
|
def _fake_backfill(session: Any, **kwargs: Any) -> dict[str, int]:
|
|
captured["session"] = session
|
|
captured.update(kwargs)
|
|
return {
|
|
"enumerated_features": 5,
|
|
"unique_zones": 3,
|
|
"cached_before": 1,
|
|
"fetched": 2,
|
|
"upserted": 2,
|
|
"failed": 0,
|
|
}
|
|
|
|
monkeypatch.setattr(task_mod, "SessionLocal", lambda: db)
|
|
monkeypatch.setattr(task_mod, "EKBGeoportalClient", lambda *a, **kw: object())
|
|
monkeypatch.setattr(task_mod, "backfill_ekb_zone_regulations", _fake_backfill)
|
|
|
|
result = task_mod.backfill_zone_regulations(limit=2, rate_delay_s=0.0)
|
|
|
|
assert result["upserted"] == 2
|
|
assert captured["limit"] == 2
|
|
assert captured["rate_delay_s"] == 0.0
|
|
assert captured["session"] is db
|
|
assert db.closed is True # finally: db.close()
|