"""Tests for user-timezone helpers (services/tz.py).""" from datetime import datetime from unittest.mock import AsyncMock, patch from zoneinfo import ZoneInfo import pytest @pytest.mark.asyncio async def test_get_user_tz_returns_configured_zone(): from scribe.services import tz as tz_mod with patch.object(tz_mod, "get_setting", AsyncMock(return_value="America/New_York")): zone = await tz_mod.get_user_tz(1) assert zone == ZoneInfo("America/New_York") @pytest.mark.asyncio async def test_get_user_tz_falls_back_to_utc_on_bad_input(): from scribe.services import tz as tz_mod with patch.object(tz_mod, "get_setting", AsyncMock(return_value="Not/AZone")): zone = await tz_mod.get_user_tz(1) assert zone == ZoneInfo("UTC") @pytest.mark.asyncio async def test_user_day_date_before_4am_returns_yesterday(): """00:00–03:59 local still shows yesterday's day_date.""" from scribe.services import tz as tz_mod ny = ZoneInfo("America/New_York") # 02:00 NY on 2026-04-13 → day_date = 2026-04-12 (still pre-rollover) fake_now = datetime(2026, 4, 13, 2, 0, tzinfo=ny) class _FakeDatetime(datetime): @classmethod def now(cls, tz=None): return fake_now with patch.object(tz_mod, "get_user_tz", AsyncMock(return_value=ny)), \ patch.object(tz_mod, "datetime", _FakeDatetime): day = await tz_mod.user_day_date(1) assert day.isoformat() == "2026-04-12" @pytest.mark.asyncio async def test_user_day_date_after_4am_returns_today(): from scribe.services import tz as tz_mod ny = ZoneInfo("America/New_York") fake_now = datetime(2026, 4, 13, 4, 30, tzinfo=ny) class _FakeDatetime(datetime): @classmethod def now(cls, tz=None): return fake_now with patch.object(tz_mod, "get_user_tz", AsyncMock(return_value=ny)), \ patch.object(tz_mod, "datetime", _FakeDatetime): day = await tz_mod.user_day_date(1) assert day.isoformat() == "2026-04-13"