"""Тесты для ЕКБ bbox-хелперов geocoder (#1871). Покрывают: - is_within_ekb_bbox_wide — ingest-guard (avito_detail координаты); - is_within_ekb_bbox — geocoder tight-фильтр (поведение НЕ изменилось после DRY-рефактора); - инвариант WIDE ⊇ TIGHT. """ import pytest from app.services.geocoder import ( EKB_BBOX_TIGHT, EKB_BBOX_WIDE, is_within_ekb_bbox, is_within_ekb_bbox_wide, ) # Центр ЕКБ (Плотинка) — внутри обоих bbox. EKB_CENTER = (56.838, 60.605) @pytest.mark.parametrize( "lat,lon,expected", [ (*EKB_CENTER, True), # центр ЕКБ (56.797713, 60.609135, True), # реальная EKB-карточка из avito-fixture (59.9386, 30.3141, False), # Питер (#1871) (57.1530, 65.5343, False), # Тюмень (#1871) (54.7388, 55.9721, False), # Уфа (#1871) (57.0, 60.5, True), # приграничье севернее tight, но в wide (В.Пышма зона) ], ) def test_is_within_ekb_bbox_wide(lat: float, lon: float, expected: bool) -> None: assert is_within_ekb_bbox_wide(lat, lon) is expected @pytest.mark.parametrize( "lat,lon", [ (56.6, 60.3), # юго-западный угол wide (57.1, 60.9), # северо-восточный угол wide (56.6, 60.9), # юго-восточный угол (57.1, 60.3), # северо-западный угол ], ) def test_wide_bbox_boundary_inclusive(lat: float, lon: float) -> None: """Границы wide-bbox включаются (inclusive).""" assert is_within_ekb_bbox_wide(lat, lon) is True def test_wide_bbox_just_outside() -> None: """Чуть за границей wide-bbox → False.""" assert is_within_ekb_bbox_wide(56.59, 60.605) is False # южнее assert is_within_ekb_bbox_wide(57.11, 60.605) is False # севернее assert is_within_ekb_bbox_wide(56.838, 60.29) is False # западнее assert is_within_ekb_bbox_wide(56.838, 60.91) is False # восточнее def test_tight_bbox_behavior_unchanged() -> None: """geocoder tight-фильтр: те же числа, что и до DRY-рефактора (60.40-60.85 / 56.65-56.95).""" # внутри assert is_within_ekb_bbox(56.838, 60.605) is True # границы tight inclusive assert is_within_ekb_bbox(56.65, 60.40) is True assert is_within_ekb_bbox(56.95, 60.85) is True # чуть за tight → False (но в wide) assert is_within_ekb_bbox(56.64, 60.605) is False assert is_within_ekb_bbox(56.96, 60.605) is False assert is_within_ekb_bbox(56.838, 60.39) is False assert is_within_ekb_bbox(56.838, 60.86) is False def test_wide_strictly_contains_tight() -> None: """Инвариант: всё, что прошло бы tight, проходит и wide. Гарантирует, что ingest-guard не режет ничего, что geocoder сам бы пропустил. """ t_lat_min, t_lat_max, t_lon_min, t_lon_max = EKB_BBOX_TIGHT w_lat_min, w_lat_max, w_lon_min, w_lon_max = EKB_BBOX_WIDE assert w_lat_min <= t_lat_min assert w_lat_max >= t_lat_max assert w_lon_min <= t_lon_min assert w_lon_max >= t_lon_max # точечная проверка на углах tight for lat in (t_lat_min, t_lat_max): for lon in (t_lon_min, t_lon_max): assert is_within_ekb_bbox(lat, lon) is True assert is_within_ekb_bbox_wide(lat, lon) is True