gendesign/backend/tests/workers/tasks/test_gas_outlet_sync.py
bot-backend cdf493f345
All checks were successful
Deploy / changes (push) Successful in 9s
Deploy Trade-In / changes (push) Successful in 13s
Deploy / build-frontend (push) Has been skipped
Deploy / deploy-caddy (push) Has been skipped
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-browser (push) Has been skipped
Deploy / build-backend (push) Successful in 2m23s
Deploy Trade-In / test (push) Successful in 3m56s
Deploy / build-worker (push) Successful in 4m16s
Deploy Trade-In / build-backend (push) Successful in 1m19s
Deploy / deploy (push) Successful in 1m49s
Deploy / deploy-status (push) Successful in 1s
Deploy / perimeter-smoke (push) Successful in 12s
Deploy Trade-In / deploy (push) Successful in 2m25s
Deploy Trade-In / deploy-status (push) Successful in 1s
Deploy Trade-In / perimeter-smoke (push) Successful in 11s
chore(format): нормализация под ruff 0.15.20 — 161 файл, только формат (#2864) (#3022)
2026-08-21 12:01:52 +00:00

106 lines
4.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Smoke-тесты Celery-обвязки точек выхода газосети (#2119 Фаза B2, PR-4).
- sync_gas_outlet_points зарегистрирована (module в include-списке celery_app);
- beat содержит gas-outlet-points-sync-weekly (еженедельно, вторник);
- таск дважды дёргает лоадер: load_gas_outlet_points → geocode_gas_outlets(apply=True),
каждый шаг graceful (сбой одного не роняет второй) — mock без сети/БД.
"""
from __future__ import annotations
from unittest.mock import patch
def test_task_registered_in_celery_include() -> None:
"""Модуль connection_capacity_sync в include-списке celery_app."""
from app.workers.celery_app import celery_app
assert "app.workers.tasks.connection_capacity_sync" in celery_app.conf.include
def test_beat_schedule_includes_gas_outlet_sync_weekly_tuesday() -> None:
"""gas-outlet-points-sync-weekly зарегистрирована еженедельно во вторник."""
from app.workers import beat_schedule
# build_beat_schedule читает DB → мокаем _build_beat_schedule_from_db,
# чтобы тест не зависел от живого Postgres.
with patch.object(beat_schedule, "_build_beat_schedule_from_db", return_value={}):
schedule = beat_schedule.build_beat_schedule()
assert "gas-outlet-points-sync-weekly" in schedule, (
f"gas-outlet-points-sync-weekly отсутствует в beat: {sorted(schedule.keys())}"
)
entry = schedule["gas-outlet-points-sync-weekly"]
assert entry["task"] == "tasks.connection_capacity_sync.sync_gas_outlet_points"
# crontab day_of_week = вторник (2).
assert 2 in entry["schedule"].day_of_week
def test_sync_gas_outlet_points_load_then_geocode() -> None:
"""Таск: load_gas_outlet_points → geocode_gas_outlets(apply=True), оба результата в ответе."""
from app.workers.tasks import connection_capacity_sync as ccs
load_result = {"rows": 1037, "inserted": 10, "updated": 1027}
geo_result = {"candidates": 5, "geocoded": 3, "applied": True}
with (
patch(
"app.services.site_finder.ekgas_outlet_loader.load_gas_outlet_points",
return_value=load_result,
),
patch(
"app.services.site_finder.ekgas_outlet_loader.geocode_gas_outlets",
return_value=geo_result,
) as mock_geo,
patch.object(ccs, "_log_breadcrumb"),
):
out = ccs.sync_gas_outlet_points()
assert out["load"] == load_result
assert out["geocode"] == geo_result
# геокод вызван С apply=True (реальная запись geom на проде).
assert mock_geo.call_args.kwargs.get("apply") is True
def test_sync_gas_outlet_points_geocode_failure_graceful() -> None:
"""Сбой geocode-шага не роняет таск: load-результат сохраняется, geocode → error-словарь."""
from app.workers.tasks import connection_capacity_sync as ccs
load_result = {"rows": 1037, "inserted": 0, "updated": 1037}
with (
patch(
"app.services.site_finder.ekgas_outlet_loader.load_gas_outlet_points",
return_value=load_result,
),
patch(
"app.services.site_finder.ekgas_outlet_loader.geocode_gas_outlets",
side_effect=RuntimeError("DaData quota exhausted"),
),
patch.object(ccs, "_log_breadcrumb"),
):
out = ccs.sync_gas_outlet_points()
assert out["load"] == load_result # шаг 1 не откатывается сбоем шага 2
assert "error" in out["geocode"]
assert "DaData" in out["geocode"]["error"]
def test_sync_gas_outlet_points_load_failure_still_attempts_geocode() -> None:
"""Сбой load-шага не мешает попытке geocode (шаги независимы, каждый graceful)."""
from app.workers.tasks import connection_capacity_sync as ccs
geo_result = {"candidates": 0, "geocoded": 0, "applied": True}
with (
patch(
"app.services.site_finder.ekgas_outlet_loader.load_gas_outlet_points",
side_effect=RuntimeError("ekgas catalog 503"),
),
patch(
"app.services.site_finder.ekgas_outlet_loader.geocode_gas_outlets",
return_value=geo_result,
),
patch.object(ccs, "_log_breadcrumb"),
):
out = ccs.sync_gas_outlet_points()
assert "error" in out["load"]
assert out["geocode"] == geo_result