from datetime import UTC, datetime, timedelta import pytest from markupsafe import Markup from l4d2web.services.timeago import format_time_html, humanize_delta NOW = datetime(2026, 5, 16, 12, 0, 0, tzinfo=UTC) @pytest.mark.parametrize( ("delta", "expected"), [ (timedelta(0), "now"), (timedelta(seconds=1), "1 second ago"), (timedelta(seconds=2), "2 seconds ago"), (timedelta(seconds=59), "59 seconds ago"), (timedelta(seconds=60), "1 minute ago"), (timedelta(minutes=1), "1 minute ago"), (timedelta(minutes=2), "2 minutes ago"), (timedelta(minutes=59), "59 minutes ago"), (timedelta(minutes=60), "1 hour ago"), (timedelta(hours=1), "1 hour ago"), (timedelta(hours=2), "2 hours ago"), (timedelta(hours=23), "23 hours ago"), (timedelta(hours=24), "1 day ago"), (timedelta(days=1), "1 day ago"), (timedelta(days=2), "2 days ago"), (timedelta(days=6), "6 days ago"), (timedelta(days=7), "9 May"), (timedelta(days=30), "16 Apr"), (timedelta(days=120), "16 Jan"), (timedelta(days=365), "16 May 2025"), (timedelta(days=400), "11 Apr 2025"), ], ) def test_humanize_delta_past(delta, expected): then = NOW - delta assert humanize_delta(then, now=NOW) == expected @pytest.mark.parametrize( ("delta", "expected"), [ (timedelta(seconds=1), "in 1 second"), (timedelta(seconds=2), "in 2 seconds"), (timedelta(seconds=59), "in 59 seconds"), (timedelta(seconds=60), "in 1 minute"), (timedelta(minutes=2), "in 2 minutes"), (timedelta(minutes=59), "in 59 minutes"), (timedelta(hours=1), "in 1 hour"), (timedelta(hours=23), "in 23 hours"), (timedelta(days=1), "in 1 day"), (timedelta(days=6), "in 6 days"), (timedelta(days=7), "23 May"), (timedelta(days=30), "15 Jun"), (timedelta(days=365), "16 May 2027"), ], ) def test_humanize_delta_future(delta, expected): then = NOW + delta assert humanize_delta(then, now=NOW) == expected def test_humanize_delta_accepts_naive_input_as_utc(): then_naive = (NOW - timedelta(minutes=5)).replace(tzinfo=None) assert humanize_delta(then_naive, now=NOW) == "5 minutes ago" def test_humanize_delta_accepts_naive_now_as_utc(): then = NOW - timedelta(minutes=5) now_naive = NOW.replace(tzinfo=None) assert humanize_delta(then, now=now_naive) == "5 minutes ago" def test_humanize_delta_default_now_is_datetime_now_utc(): then = datetime.now(UTC) - timedelta(seconds=3) assert humanize_delta(then) in {"3 seconds ago", "2 seconds ago", "4 seconds ago"} def test_humanize_delta_year_boundary_includes_year_when_years_differ(): now = datetime(2026, 1, 15, 12, 0, 0, tzinfo=UTC) then = datetime(2025, 11, 15, 12, 0, 0, tzinfo=UTC) assert humanize_delta(then, now=now) == "15 Nov 2025" def test_format_time_html_returns_markup(): then = NOW - timedelta(minutes=5) out = format_time_html(then, now=NOW) assert isinstance(out, Markup) def test_format_time_html_contains_time_element_with_attrs(): then = datetime(2026, 5, 16, 14, 32, 11, tzinfo=UTC) now = then + timedelta(minutes=5) out = str(format_time_html(then, now=now)) assert out.startswith("