97 lines
3 KiB
Python
97 lines
3 KiB
Python
"""Тесты для layout_signature helpers (Issue #113, Phase 2.1).
|
|
|
|
Pure-Python, без БД и external calls.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import pytest
|
|
|
|
from app.services.site_finder.layout_signature import (
|
|
area_bin,
|
|
layout_signature,
|
|
room_bucket_from_flat,
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"rooms, flat_type, is_studio, expected",
|
|
[
|
|
(None, None, True, "studio"),
|
|
(0, "Квартира-студия", False, "studio"),
|
|
(0, "Квартира", None, "studio"),
|
|
(1, "Квартира", None, "1"),
|
|
(2, "Квартира", None, "2"),
|
|
(3, "Квартира", False, "3"),
|
|
(4, "Квартира", False, "4+"),
|
|
(5, "Квартира", None, "4+"),
|
|
(None, "Квартира", None, "1"), # fallback
|
|
],
|
|
)
|
|
def test_room_bucket(
|
|
rooms: int | None, flat_type: str | None, is_studio: bool | None, expected: str
|
|
) -> None:
|
|
assert room_bucket_from_flat(rooms, flat_type, is_studio) == expected
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"area, expected",
|
|
[
|
|
(0.5, "<25"),
|
|
(24.9, "<25"),
|
|
(25.0, "25-40"),
|
|
(39.99, "25-40"),
|
|
(40.0, "40-60"),
|
|
(59.99, "40-60"),
|
|
(60.0, "60-80"),
|
|
(79.99, "60-80"),
|
|
(80.0, "80-100"),
|
|
(99.99, "80-100"),
|
|
(100.0, "100+"),
|
|
(250.0, "100+"),
|
|
],
|
|
)
|
|
def test_area_bin(area: float, expected: str) -> None:
|
|
assert area_bin(area) == expected
|
|
|
|
|
|
def test_layout_signature_deterministic() -> None:
|
|
assert layout_signature("studio", "<25") == "studio__<25"
|
|
assert layout_signature("4+", "100+") == "4+__100+"
|
|
# Same input → same output
|
|
sig1 = layout_signature("2", "40-60")
|
|
sig2 = layout_signature("2", "40-60")
|
|
assert sig1 == sig2
|
|
|
|
|
|
def test_room_bucket_is_studio_overrides_rooms() -> None:
|
|
"""is_studio=True beats any rooms value."""
|
|
assert room_bucket_from_flat(3, "Квартира", True) == "studio"
|
|
|
|
|
|
def test_room_bucket_flat_type_studio_overrides_rooms() -> None:
|
|
"""flat_type='Квартира-студия' beats rooms=2."""
|
|
assert room_bucket_from_flat(2, "Квартира-студия", None) == "studio"
|
|
|
|
|
|
def test_room_bucket_large_rooms() -> None:
|
|
"""rooms=10 → '4+'."""
|
|
assert room_bucket_from_flat(10, "Квартира", False) == "4+"
|
|
|
|
|
|
def test_area_bin_boundary_exact() -> None:
|
|
"""Граничные значения попадают в правильный бакет (включение левой границы)."""
|
|
assert area_bin(25.0) == "25-40"
|
|
assert area_bin(40.0) == "40-60"
|
|
assert area_bin(60.0) == "60-80"
|
|
assert area_bin(80.0) == "80-100"
|
|
assert area_bin(100.0) == "100+"
|
|
|
|
|
|
def test_layout_signature_format() -> None:
|
|
"""Сигнатура всегда содержит двойное подчёркивание-разделитель."""
|
|
sig = layout_signature("1", "25-40")
|
|
assert "__" in sig
|
|
parts = sig.split("__")
|
|
assert parts[0] == "1"
|
|
assert parts[1] == "25-40"
|