gendesign/tradein-mvp/backend/tests/test_avito_address_clean.py
Light1YT 78e7705a5f
All checks were successful
CI / changes (pull_request) Successful in 6s
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
fix(avito): de-glue house number from district marker in _clean_address (#1773)
Avito leaks addresses with house number glued to district marker without
separator («…Савкова, 29р-н Академический»), breaking house-number extraction
and same-house matching (41 unmatched avito listings on one street).
_clean_address now inserts ", " between a house-number token (digits +
optional Cyrillic letter + optional /N|сN|кN|корпус|стр) and a following
marker (р-н, мкр, район, г., пос, снт, …).

- avito.py: idempotent _deglue_house_marker step (CSS/tail-strip kept)
- tests: de-glue positive/negative/idempotency (24 passed)
- data/sql/124_deglue_avito_addresses.sql: idempotent backfill for stored rows

normalize.py НЕ тронут (общий fingerprint матчинга, #1534).
Закрывает avito-часть #1773 (cian-без-номера + дедуп — отдельно, зона cian).
2026-06-19 13:33:43 +05:00

82 lines
3.6 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.

import pytest
from app.services.scrapers.avito import _clean_address
def test_strips_css_noise():
raw = (
"ул. Токарей, 56к1Площадь 1905 года.css-39hgr0{fill:currentColor;"
"height:1em;box-sizing:border-box;}.css-39hgr0:focus{outline:none;}"
"от 31 мин.Геологическая.css-39hgr0{...}"
)
assert _clean_address(raw) == "ул. Токарей, 56к1"
def test_clean_address_passthrough():
assert _clean_address("ул. Малышева, 1") == "ул. Малышева, 1"
def test_clean_handles_none():
assert _clean_address(None) is None
assert _clean_address("") is None
assert _clean_address(" ") is None
def test_clean_strips_trailing_punctuation():
assert _clean_address("ул. Ленина, 5,") == "ул. Ленина, 5"
# ── #1773: де-слип номера дома и маркера района/нас.пункта ────────────────────
@pytest.mark.parametrize(
"raw,expected",
[
# реальный кейс с прода
(
"Свердловская обл., Екатеринбург, ул. Евгения Савкова, 29р-н Академический",
"Свердловская обл., Екатеринбург, ул. Евгения Савкова, 29, р-н Академический",
),
# литера дома слиплась с маркером
("ул. X, 17Ар-н Пионерский", "ул. X, 17А, р-н Пионерский"),
("ул. X, 44Бр-н Запад", "ул. X, 44Б, р-н Запад"),
# корпус через дробь
("ул. X, 35/2р-н Юг", "ул. X, 35/2, р-н Юг"),
# корпус через «с
("ул. X, 33с1р-н Центр", "ул. X, 33с1, р-н Центр"),
# прочие маркеры
("ул. X, 12мкр Солнечный", "ул. X, 12, мкр Солнечный"),
("ул. X, 5район Кировский", "ул. X, 5, район Кировский"),
("ул. X, 100к2р-н Чкаловский", "ул. X, 100к2, р-н Чкаловский"),
# маркеры населённых пунктов
("ул. X, 12с. Кашино", "ул. X, 12, с. Кашино"),
("ул. X, 10д. Малое", "ул. X, 10, д. Малое"),
("ул. X, 25г. Берёзовский", "ул. X, 25, г. Берёзовский"),
],
)
def test_deglue_house_marker(raw, expected):
assert _clean_address(raw) == expected
@pytest.mark.parametrize(
"raw",
[
# уже расклеено — идемпотентность
"ул. Евгения Савкова, 29, р-н Академический",
# нормальные адреса без склейки — разделять НЕ надо
"ул. Малышева, 1",
"ул. Токарей, 56к1",
"ул. Ленина, 5",
"ул. Серова, 45",
"г. Екатеринбург, ул. Ленина, 10",
"снт Дружба, уч. 12",
"ул. Декабристов, 16",
],
)
def test_deglue_negative_no_change(raw):
# для этих строк де-слип не должен ничего менять (кроме штатного strip пунктуации)
assert _clean_address(raw) == raw.strip(" ,.\n\t")
def test_deglue_idempotent():
once = _clean_address("ул. Евгения Савкова, 29р-н Академический")
twice = _clean_address(once)
assert once == twice == "ул. Евгения Савкова, 29, р-н Академический"