conftest.py 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. """Shared test fixtures.
  2. Provides a configurable in-memory repository (daily history + a single rolling
  3. row) so the funnel service and API can be tested without Postgres.
  4. """
  5. from __future__ import annotations
  6. import pytest
  7. from app.services.funnel import FunnelSnapshot
  8. class FakeRepository:
  9. """In-memory repository implementing the FunnelRepository protocol.
  10. * ``set_daily(dt, values)`` installs a daily row keyed by ``dt`` (yyyyMMdd).
  11. * ``set_latest_daily(dt)`` marks which daily ``dt`` is returned when
  12. ``fetch_daily(None)`` is called (defaults to the most recently added dt).
  13. * ``set_rolling(dt, values)`` installs the single rolling row.
  14. With nothing installed both fetches return ``None``.
  15. """
  16. def __init__(self) -> None:
  17. self._daily: dict[str, dict[str, int | None]] = {}
  18. self._latest_daily_dt: str | None = None
  19. self._rolling: FunnelSnapshot | None = None
  20. def set_daily(self, dt: str, values: dict[str, int | None]) -> None:
  21. self._daily[dt] = dict(values)
  22. self._latest_daily_dt = dt
  23. def set_latest_daily(self, dt: str) -> None:
  24. self._latest_daily_dt = dt
  25. def set_rolling(self, dt: str, values: dict[str, int | None]) -> None:
  26. self._rolling = FunnelSnapshot(dt=dt, values=dict(values))
  27. def clear(self) -> None:
  28. self._daily.clear()
  29. self._latest_daily_dt = None
  30. self._rolling = None
  31. async def fetch_daily(self, dt: str | None) -> FunnelSnapshot | None:
  32. if dt is None:
  33. dt = self._latest_daily_dt
  34. if dt is None:
  35. return None
  36. values = self._daily.get(dt)
  37. if values is None:
  38. return None
  39. return FunnelSnapshot(dt=dt, values=dict(values))
  40. async def fetch_rolling(self) -> FunnelSnapshot | None:
  41. return self._rolling
  42. @pytest.fixture
  43. def repo() -> FakeRepository:
  44. return FakeRepository()