Coverage for src/lexigram/auth/admin/handlers/token_refresh_rate.py: 100%
18 statements
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-26 00:58 +0800
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-26 00:58 +0800
1"""Token refresh rate widget handler."""
3from __future__ import annotations
5from lexigram.auth.services.activity_tracker import AuthActivityTracker
6from lexigram.contracts.admin import Stat, StatContent, WidgetParams
7from lexigram.contracts.admin.errors import AdminError
8from lexigram.result import Ok, Result
11class TokenRefreshRateWidgetHandler:
12 """Handler for the token refresh rate widget.
14 Args:
15 tracker: injected AuthActivityTracker.
16 """
18 def __init__(self, tracker: AuthActivityTracker) -> None:
19 """Initialize handler with the activity tracker.
21 Args:
22 tracker: AuthActivityTracker for token metrics.
23 """
24 self._tracker = tracker
26 async def get_data(self, params: WidgetParams) -> Result[StatContent, AdminError]:
27 """Fetch token refresh rate data.
29 Mirrors the widget template: the rate is rendered with one decimal
30 and neutral styling, and the total line is shown only when non-zero —
31 no tone/threshold ladder exists in the template.
33 Infrastructure failures propagate as exceptions.
35 Args:
36 params: Widget parameters (includes time_window_minutes).
38 Returns:
39 Result containing StatContent or AdminError.
40 """
41 window = getattr(params, "time_window_minutes", 30)
42 refreshes_per_minute, total_refreshes = self._tracker.refresh_summary(
43 window_minutes=int(window or 30)
44 )
45 return Ok(
46 self._build_content(
47 refreshes_per_minute=refreshes_per_minute,
48 total_refreshes=total_refreshes,
49 )
50 )
52 def _build_content(
53 self, refreshes_per_minute: float, total_refreshes: int
54 ) -> StatContent:
55 """Build the StatContent mirroring the widget template.
57 Args:
58 refreshes_per_minute: Token refreshes per minute.
59 total_refreshes: Total refresh count.
61 Returns:
62 StatContent with neutral styling and a conditional total stat.
63 """
64 stats: list[Stat] = [
65 Stat(
66 label="Refresh Rate (per minute)",
67 value=f"{refreshes_per_minute:.1f}",
68 ),
69 ]
70 if total_refreshes > 0:
71 stats.append(Stat(label="Total refreshes", value=str(total_refreshes)))
72 return StatContent(stats=tuple(stats))
75__all__ = ["TokenRefreshRateWidgetHandler"]