test_validation.py 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. """Tests for period validation, period -> column mapping, and snapshot_dt rules."""
  2. from __future__ import annotations
  3. from datetime import date, timedelta
  4. import pytest
  5. from app.schemas import FunnelQueryRequest, Period
  6. from app.services.funnel import (
  7. ROLLING_SUFFIX,
  8. SnapshotDateError,
  9. daily_columns,
  10. rolling_columns,
  11. validate_snapshot_dt,
  12. )
  13. def test_period_accepts_three_valid_values() -> None:
  14. for value in ("day", "last_7d", "last_30d"):
  15. req = FunnelQueryRequest(period=value)
  16. assert req.period.value == value
  17. def test_period_rejects_bad_value() -> None:
  18. with pytest.raises(ValueError):
  19. FunnelQueryRequest(period="yesterday") # old v2 value, now invalid
  20. def test_request_snapshot_dt_optional() -> None:
  21. req = FunnelQueryRequest(period="day")
  22. assert req.snapshot_dt is None
  23. req2 = FunnelQueryRequest(period="day", snapshot_dt="2026-06-20")
  24. assert req2.snapshot_dt == date(2026, 6, 20)
  25. def test_rolling_suffix_mapping() -> None:
  26. assert ROLLING_SUFFIX[Period.last_7d] == "7d"
  27. assert ROLLING_SUFFIX[Period.last_30d] == "30d"
  28. def test_daily_columns() -> None:
  29. assert daily_columns() == [
  30. "uv_start",
  31. "uv_show",
  32. "uv_detail",
  33. "uv_order",
  34. "uv_paid",
  35. ]
  36. def test_rolling_columns_last_7d() -> None:
  37. assert rolling_columns(Period.last_7d) == [
  38. "uv_start_7d",
  39. "uv_show_7d",
  40. "uv_detail_7d",
  41. "uv_order_7d",
  42. "uv_paid_7d",
  43. ]
  44. def test_rolling_columns_last_30d() -> None:
  45. assert rolling_columns(Period.last_30d) == [
  46. "uv_start_30d",
  47. "uv_show_30d",
  48. "uv_detail_30d",
  49. "uv_order_30d",
  50. "uv_paid_30d",
  51. ]
  52. def test_validate_snapshot_dt_accepts_yesterday() -> None:
  53. yesterday = date.today() - timedelta(days=1)
  54. validate_snapshot_dt(yesterday) # no raise
  55. def test_validate_snapshot_dt_accepts_old_date() -> None:
  56. validate_snapshot_dt(date.today() - timedelta(days=30)) # no raise
  57. def test_validate_snapshot_dt_rejects_today() -> None:
  58. with pytest.raises(SnapshotDateError):
  59. validate_snapshot_dt(date.today())
  60. def test_validate_snapshot_dt_rejects_future() -> None:
  61. with pytest.raises(SnapshotDateError):
  62. validate_snapshot_dt(date.today() + timedelta(days=1))