fix(sf): verify=False для екатеринбург.рф (CA Минцифры) + синтетический CI-тест КРТ-парсера (ревью #1126)
This commit is contained in:
parent
d966b968fd
commit
c087bd74b1
2 changed files with 64 additions and 1 deletions
|
|
@ -70,7 +70,12 @@ def fetch_krt_page() -> str:
|
||||||
Сеть отделена от парсинга для testability.
|
Сеть отделена от парсинга для testability.
|
||||||
Raises: httpx.HTTPError при недоступности сервера.
|
Raises: httpx.HTTPError при недоступности сервера.
|
||||||
"""
|
"""
|
||||||
with httpx.Client(headers=_HEADERS, timeout=30, follow_redirects=True) as client:
|
with httpx.Client(
|
||||||
|
headers=_HEADERS,
|
||||||
|
timeout=30,
|
||||||
|
follow_redirects=True,
|
||||||
|
verify=False, # CA Минцифры РФ — нет в certifi. Аналог ekburg_permits.py #242.
|
||||||
|
) as client:
|
||||||
resp = client.get(KRT_URL)
|
resp = client.get(KRT_URL)
|
||||||
resp.raise_for_status()
|
resp.raise_for_status()
|
||||||
logger.info(
|
logger.info(
|
||||||
|
|
|
||||||
|
|
@ -139,6 +139,64 @@ class TestEmptyAndGarbage:
|
||||||
assert parse_krt_page(html) == []
|
assert parse_krt_page(html) == []
|
||||||
|
|
||||||
|
|
||||||
|
# ── Синтетический блок: площадка без застройщика / договора / цен ─────────────
|
||||||
|
# Имитирует площадки «в работе» (только geography + технические параметры).
|
||||||
|
# Не требует локального дампа — всегда исполняется в CI.
|
||||||
|
_BABUSHKINA_BLOCK = textwrap.dedent(
|
||||||
|
"""\
|
||||||
|
<h2><strong>2024 год</strong></h2>
|
||||||
|
<p> <strong>1. КРТ жилой застройки в районе ул. Бабушкина:</strong></p>
|
||||||
|
<p>Площадь территории: 5,10 га;<br />\
|
||||||
|
Градостроительный потенциал: 120 000 кв. м;<br />\
|
||||||
|
Всего многоквартирных домов: 18;<br />\
|
||||||
|
3. Издано Постановление Администрации города Екатеринбурга от 15.01.2024 № 42 \
|
||||||
|
«О комплексном развитии территории».</p>
|
||||||
|
<p><strong>Стадия реализации: проектирование</strong></p>
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class TestParseBabushkinaBlock:
|
||||||
|
"""Синтетический тест: площадка без застройщика, договора и цен аукциона.
|
||||||
|
|
||||||
|
Не зависит от локального дампа — всегда запускается в CI.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.fixture(scope="class")
|
||||||
|
def site(self):
|
||||||
|
sites = parse_krt_page(_BABUSHKINA_BLOCK)
|
||||||
|
assert sites, "parse_krt_page вернул пустой список для синтетического блока"
|
||||||
|
return sites[0]
|
||||||
|
|
||||||
|
def test_parses_exactly_one_site(self):
|
||||||
|
"""Синтетический блок содержит ровно одну площадку."""
|
||||||
|
assert len(parse_krt_page(_BABUSHKINA_BLOCK)) == 1
|
||||||
|
|
||||||
|
def test_developer_is_none(self, site):
|
||||||
|
"""Застройщик не указан → None."""
|
||||||
|
assert site.developer_name is None
|
||||||
|
|
||||||
|
def test_contract_number_is_none(self, site):
|
||||||
|
"""Договор не заключён → None."""
|
||||||
|
assert site.contract_number is None
|
||||||
|
|
||||||
|
def test_area_ha_filled(self, site):
|
||||||
|
"""Площадь территории заполнена."""
|
||||||
|
assert site.area_ha == pytest.approx(5.10, rel=1e-3)
|
||||||
|
|
||||||
|
def test_gradpotential_filled(self, site):
|
||||||
|
"""Градостроительный потенциал заполнен."""
|
||||||
|
assert site.gradpotential_sqm == pytest.approx(120000.0, rel=1e-3)
|
||||||
|
|
||||||
|
def test_district_filled(self, site):
|
||||||
|
"""Район извлечён из названия блока."""
|
||||||
|
assert site.district is not None
|
||||||
|
assert "Бабушкина" in site.district
|
||||||
|
|
||||||
|
def test_krt_kind(self, site):
|
||||||
|
assert site.krt_kind == "жилой застройки"
|
||||||
|
|
||||||
|
|
||||||
class TestMultiSiteCountFromDump:
|
class TestMultiSiteCountFromDump:
|
||||||
"""Проверка количества площадок из реального дампа страницы."""
|
"""Проверка количества площадок из реального дампа страницы."""
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue