88 lines
2.8 KiB
Python
88 lines
2.8 KiB
Python
from __future__ import annotations
|
|
|
|
from datetime import datetime, timedelta
|
|
|
|
import pytest
|
|
|
|
from app.api import metrics as metrics_api
|
|
from app.schemas.metrics import DashboardRangeKey
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("range_key", "expected_bucket", "expected_duration"),
|
|
[
|
|
("24h", "hour", timedelta(hours=24)),
|
|
("3d", "day", timedelta(days=3)),
|
|
("7d", "day", timedelta(days=7)),
|
|
("14d", "day", timedelta(days=14)),
|
|
("1m", "day", timedelta(days=30)),
|
|
("3m", "week", timedelta(days=90)),
|
|
("6m", "week", timedelta(days=180)),
|
|
("1y", "month", timedelta(days=365)),
|
|
],
|
|
)
|
|
def test_resolve_range_maps_expected_window(
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
range_key: DashboardRangeKey,
|
|
expected_bucket: str,
|
|
expected_duration: timedelta,
|
|
) -> None:
|
|
fixed_now = datetime(2026, 2, 12, 15, 30, 0)
|
|
monkeypatch.setattr(metrics_api, "utcnow", lambda: fixed_now)
|
|
|
|
spec = metrics_api._resolve_range(range_key)
|
|
|
|
assert spec.key == range_key
|
|
assert spec.bucket == expected_bucket
|
|
assert spec.duration == expected_duration
|
|
assert spec.start == fixed_now - expected_duration
|
|
assert spec.end == fixed_now
|
|
|
|
|
|
def test_comparison_range_is_previous_window(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
fixed_now = datetime(2026, 2, 12, 15, 30, 0)
|
|
monkeypatch.setattr(metrics_api, "utcnow", lambda: fixed_now)
|
|
primary = metrics_api._resolve_range("14d")
|
|
|
|
comparison = metrics_api._comparison_range(primary)
|
|
|
|
assert comparison.key == primary.key
|
|
assert comparison.bucket == primary.bucket
|
|
assert comparison.duration == primary.duration
|
|
assert comparison.start == primary.start - primary.duration
|
|
assert comparison.end == primary.end - primary.duration
|
|
|
|
|
|
def test_week_buckets_align_to_monday(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
fixed_now = datetime(2026, 2, 12, 15, 30, 0)
|
|
monkeypatch.setattr(metrics_api, "utcnow", lambda: fixed_now)
|
|
spec = metrics_api._resolve_range("3m")
|
|
|
|
buckets = metrics_api._build_buckets(spec)
|
|
|
|
assert buckets
|
|
assert all(bucket.weekday() == 0 for bucket in buckets)
|
|
assert all(
|
|
buckets[index + 1] - buckets[index] == timedelta(days=7)
|
|
for index in range(len(buckets) - 1)
|
|
)
|
|
|
|
|
|
def test_month_buckets_align_to_first_of_month(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
fixed_now = datetime(2026, 2, 12, 15, 30, 0)
|
|
monkeypatch.setattr(metrics_api, "utcnow", lambda: fixed_now)
|
|
spec = metrics_api._resolve_range("1y")
|
|
|
|
buckets = metrics_api._build_buckets(spec)
|
|
|
|
assert buckets
|
|
assert all(
|
|
bucket.day == 1
|
|
and bucket.hour == 0
|
|
and bucket.minute == 0
|
|
and bucket.second == 0
|
|
and bucket.microsecond == 0
|
|
for bucket in buckets
|
|
)
|
|
assert len(buckets) >= 12
|