gendesign/backend/tests/workers/test_backfill_zone_regulations.py
Light1YT 2ff34b1500
Some checks failed
CI / changes (pull_request) Successful in 7s
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Failing after 1m48s
CI / backend-tests (pull_request) Successful in 9m56s
feat(site-finder): backfill ЕКБ зон-регламента — разблокировать видимость финмодели (#1881)
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
2026-06-24 02:11:41 +05:00

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()