gendesign/tradein-mvp/backend/tests/test_estimator_sber_time_adjust.py
lekss361 3bd107f923
All checks were successful
Deploy Trade-In / changes (push) Successful in 5s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / test (push) Successful in 33s
Deploy Trade-In / build-backend (push) Successful in 45s
Deploy Trade-In / deploy (push) Successful in 45s
test(tradein): fix #794 test regressions on main (broken by #919 early squash-merge) (#921)
Co-authored-by: lekss361 <lekss361@gendsgn.local>
Co-committed-by: lekss361 <lekss361@gendsgn.local>
2026-05-31 19:05:10 +00:00

80 lines
3.1 KiB
Python

"""Tests for #794 СберИндекс time-adjustment helper — pure, no DB."""
from __future__ import annotations
import os
import sys
from datetime import date
from unittest.mock import MagicMock
# DATABASE_URL required by pydantic Settings before any app import.
os.environ.setdefault("DATABASE_URL", "postgresql+psycopg://test:test@localhost:5432/test")
# WeasyPrint stub — not installed in CI без GTK.
sys.modules.setdefault("weasyprint", MagicMock())
from app.services.estimator import ( # noqa: E402
SBER_TIME_FACTOR_MAX,
SBER_TIME_FACTOR_MIN,
_sber_time_factor,
)
def test_empty_series_returns_one() -> None:
assert _sber_time_factor({}, date(2026, 1, 1)) == 1.0
def test_deal_month_equals_latest_returns_one() -> None:
series = {date(2026, 1, 1): 95_000.0, date(2026, 4, 1): 100_000.0}
assert _sber_time_factor(series, date(2026, 4, 1)) == 1.0
def test_deal_month_after_latest_returns_one() -> None:
series = {date(2026, 1, 1): 95_000.0, date(2026, 4, 1): 100_000.0}
assert _sber_time_factor(series, date(2026, 6, 1)) == 1.0
def test_normal_factor_calculation() -> None:
series = {date(2026, 1, 1): 95_000.0, date(2026, 4, 1): 100_000.0}
factor = _sber_time_factor(series, date(2026, 1, 1))
expected = 100_000.0 / 95_000.0 # ≈ 1.0526
assert abs(factor - expected) < 0.0001
assert SBER_TIME_FACTOR_MIN <= factor <= SBER_TIME_FACTOR_MAX
def test_clamp_high() -> None:
"""Very old deal → factor would be >>1.6 → clamp to SBER_TIME_FACTOR_MAX."""
series = {date(2020, 1, 1): 10_000.0, date(2026, 4, 1): 100_000.0}
factor = _sber_time_factor(series, date(2020, 1, 1))
assert factor == SBER_TIME_FACTOR_MAX
def test_clamp_low() -> None:
"""Series shows price drop → factor <<0.7 → clamp to SBER_TIME_FACTOR_MIN."""
series = {date(2020, 1, 1): 200_000.0, date(2026, 4, 1): 50_000.0}
factor = _sber_time_factor(series, date(2020, 1, 1))
assert factor == SBER_TIME_FACTOR_MIN
def test_missing_month_uses_nearest_earlier() -> None:
"""deal_month=2026-02 not in series; nearest earlier is 2026-01."""
series = {date(2026, 1, 1): 95_000.0, date(2026, 4, 1): 100_000.0}
# Using 2026-01 as base: factor = 100000/95000
factor_with_missing = _sber_time_factor(series, date(2026, 2, 1))
factor_explicit = _sber_time_factor(series, date(2026, 1, 1))
assert abs(factor_with_missing - factor_explicit) < 0.0001
def test_deal_older_than_series_uses_earliest() -> None:
"""Deal month before all series data → use earliest available month."""
series = {date(2023, 1, 1): 80_000.0, date(2026, 4, 1): 100_000.0}
# deal at 2020-01 is before series start → base = series[2023-01] = 80000
factor = _sber_time_factor(series, date(2020, 1, 1))
expected = min(100_000.0 / 80_000.0, SBER_TIME_FACTOR_MAX)
assert abs(factor - expected) < 0.0001
def test_zero_base_returns_one() -> None:
"""Zero index value in series → guard → return 1.0."""
series = {date(2026, 1, 1): 0.0, date(2026, 4, 1): 100_000.0}
assert _sber_time_factor(series, date(2026, 1, 1)) == 1.0