test_stats_local_days.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. """A Stats date filter takes the local calendar day (DB-C12)."""
  2. from datetime import datetime
  3. import pytest
  4. from httpx import AsyncClient
  5. from backend.app.models.print_log import PrintLogEntry
  6. pytestmark = [pytest.mark.asyncio, pytest.mark.integration]
  7. async def test_a_print_at_half_past_one_in_berlin_counts_for_that_day(
  8. async_client: AsyncClient, printer_factory, db_session, monkeypatch
  9. ):
  10. monkeypatch.setenv("TZ", "Europe/Berlin")
  11. printer = await printer_factory()
  12. # 01:30 on 16 October in Berlin is 23:30 on the 15th in UTC.
  13. db_session.add(
  14. PrintLogEntry(
  15. print_name="late night",
  16. printer_id=printer.id,
  17. status="completed",
  18. created_at=datetime(2026, 10, 15, 23, 30),
  19. )
  20. )
  21. await db_session.commit()
  22. sixteenth = await async_client.get("/api/v1/archives/slim?date_from=2026-10-16&date_to=2026-10-16")
  23. fifteenth = await async_client.get("/api/v1/archives/slim?date_from=2026-10-15&date_to=2026-10-15")
  24. assert [r["print_name"] for r in sixteenth.json()] == ["late night"]
  25. assert fifteenth.json() == []
  26. async def test_the_statistics_totals_take_the_local_day(
  27. async_client: AsyncClient, printer_factory, db_session, monkeypatch
  28. ):
  29. monkeypatch.setenv("TZ", "Europe/Berlin")
  30. printer = await printer_factory()
  31. db_session.add(
  32. PrintLogEntry(
  33. print_name="late night", printer_id=printer.id, status="failed", created_at=datetime(2026, 10, 15, 23, 30)
  34. )
  35. )
  36. await db_session.commit()
  37. stats = (await async_client.get("/api/v1/archives/stats?date_from=2026-10-16&date_to=2026-10-16")).json()
  38. failures = (
  39. await async_client.get("/api/v1/archives/analysis/failures?date_from=2026-10-16&date_to=2026-10-16")
  40. ).json()
  41. assert stats["total_prints"] == 1
  42. assert failures["total_prints"] == 1
  43. async def test_the_archive_list_takes_the_local_day(
  44. async_client: AsyncClient, printer_factory, archive_factory, db_session, monkeypatch
  45. ):
  46. monkeypatch.setenv("TZ", "Europe/Berlin")
  47. printer = await printer_factory()
  48. archive = await archive_factory(printer.id, print_name="late night")
  49. archive.created_at = datetime(2026, 10, 15, 23, 30)
  50. await db_session.commit()
  51. listed = (await async_client.get("/api/v1/archives/?date_from=2026-10-16&date_to=2026-10-16")).json()
  52. assert [a["id"] for a in listed] == [archive.id]
  53. # The browser's own zone, sent with its dates: a browser away from the
  54. # server's TZ (the Docker default is Europe/Berlin) shifted every day.
  55. TOKYO_EARLY = datetime(2026, 10, 16, 23, 30) # 08:30 on 17 October in Tokyo
  56. async def _tokyo_morning_print(printer_factory, db_session, monkeypatch):
  57. monkeypatch.setenv("TZ", "UTC")
  58. printer = await printer_factory()
  59. db_session.add(PrintLogEntry(print_name="morning", printer_id=printer.id, status="failed", created_at=TOKYO_EARLY))
  60. await db_session.commit()
  61. return printer
  62. @pytest.mark.parametrize(
  63. ("path", "count"),
  64. [
  65. ("/api/v1/archives/slim", lambda body: len(body)),
  66. ("/api/v1/archives/stats", lambda body: body["total_prints"]),
  67. ("/api/v1/archives/analysis/failures", lambda body: body["total_prints"]),
  68. ],
  69. )
  70. async def test_the_dates_are_days_in_the_zone_the_caller_names(
  71. async_client: AsyncClient, printer_factory, db_session, monkeypatch, path, count
  72. ):
  73. await _tokyo_morning_print(printer_factory, db_session, monkeypatch)
  74. tokyo_17th = (await async_client.get(f"{path}?date_from=2026-10-17&date_to=2026-10-17&tz=Asia/Tokyo")).json()
  75. server_17th = (await async_client.get(f"{path}?date_from=2026-10-17&date_to=2026-10-17")).json()
  76. assert count(tokyo_17th) == 1
  77. assert count(server_17th) == 0
  78. async def test_an_unknown_zone_falls_back_to_the_server_s(
  79. async_client: AsyncClient, printer_factory, db_session, monkeypatch
  80. ):
  81. await _tokyo_morning_print(printer_factory, db_session, monkeypatch)
  82. response = await async_client.get("/api/v1/archives/slim?date_from=2026-10-16&date_to=2026-10-16&tz=Mars/Olympus")
  83. assert response.status_code == 200
  84. assert len(response.json()) == 1