gateway/tests/test_dateRange.py
2026-04-21 00:50:36 +02:00

94 lines
3.1 KiB
Python

# Copyright (c) 2025 Patrick Motsch
# All rights reserved.
"""
Unit tests for `modules.shared.dateRange`.
Pure-Python, no DB / no API.
"""
from datetime import date, datetime, time as dtTime
import pytest
from fastapi import HTTPException
from modules.shared.dateRange import (
daysInRange,
isoDateRangeToLocalEpoch,
parseIsoDate,
parseIsoDateRange,
)
class TestParseIsoDate:
def test_validIsoDate(self):
assert parseIsoDate("2026-04-15", "dateFrom") == date(2026, 4, 15)
def test_emptyStringRaises400(self):
with pytest.raises(HTTPException) as exc:
parseIsoDate("", "dateFrom")
assert exc.value.status_code == 400
assert "dateFrom" in exc.value.detail
def test_invalidFormatRaises400(self):
with pytest.raises(HTTPException) as exc:
parseIsoDate("15.04.2026", "dateTo")
assert exc.value.status_code == 400
assert "dateTo" in exc.value.detail
assert "15.04.2026" in exc.value.detail
def test_nonStringRaises400(self):
with pytest.raises(HTTPException) as exc:
parseIsoDate(None, "dateFrom") # type: ignore[arg-type]
assert exc.value.status_code == 400
class TestParseIsoDateRange:
def test_validRange(self):
f, t = parseIsoDateRange("2026-04-01", "2026-04-15")
assert f == date(2026, 4, 1)
assert t == date(2026, 4, 15)
def test_sameDayIsValid(self):
f, t = parseIsoDateRange("2026-04-15", "2026-04-15")
assert f == t
def test_invertedRangeRaises400(self):
with pytest.raises(HTTPException) as exc:
parseIsoDateRange("2026-04-15", "2026-04-01")
assert exc.value.status_code == 400
assert "dateFrom must be <= dateTo" in exc.value.detail
class TestIsoDateRangeToLocalEpoch:
def test_inclusiveEndOfDay(self):
"""`dateTo` boundary covers full last day (23:59:59.999999 local)."""
fromTs, toTs = isoDateRangeToLocalEpoch("2026-04-15", "2026-04-15")
startOfDay = datetime.combine(date(2026, 4, 15), dtTime.min).timestamp()
endOfDay = datetime.combine(date(2026, 4, 15), dtTime.max).timestamp()
assert fromTs == startOfDay
assert toTs == endOfDay
# Single-day range covers ~24h - 1 microsecond.
assert (toTs - fromTs) > (24 * 3600 - 1)
def test_multiDayRange(self):
fromTs, toTs = isoDateRangeToLocalEpoch("2026-04-01", "2026-04-03")
# Three local days, end-inclusive: ~3 * 86400 seconds (- 1us).
assert 3 * 86400 - 1 < (toTs - fromTs) < 3 * 86400 + 1
def test_invalidRaises400(self):
with pytest.raises(HTTPException):
isoDateRangeToLocalEpoch("not-a-date", "2026-04-03")
class TestDaysInRange:
def test_singleDayIsOne(self):
assert daysInRange("2026-04-15", "2026-04-15") == 1
def test_threeDaysInclusive(self):
assert daysInRange("2026-04-01", "2026-04-03") == 3
def test_yearSpan(self):
assert daysInRange("2026-01-01", "2026-12-31") == 365
def test_invertedRangeRaises400(self):
with pytest.raises(HTTPException):
daysInRange("2026-04-15", "2026-04-01")