#5207 "UniFi Overview tab: func.strftime is SQLite-only": the WAN and client sparklines bucketed with strftime('%s'), which Postgres lacks, so /plugins/unifi/rows failed. Traefik's date_bin bucket moves to core/time_range.time_bucket and both plugins use it. Devices list offline and failing first, and a state other than online is named (Upgrading, Adopting, Heartbeat missed...) instead of drawn as Down. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
48 lines
2.7 KiB
Python
48 lines
2.7 KiB
Python
"""UniFi's overview reads in the shared shapes: WAN health as stat tiles graded
|
|
by Settings → Thresholds, devices with status dots, categories as badges (#5126)."""
|
|
from datetime import datetime, timezone
|
|
from types import SimpleNamespace as NS
|
|
|
|
from plugins.unifi.routes import device_state, devices_in_order
|
|
from tests._templates import render_plugin_template
|
|
from tests.test_style_tokens import hex_colours
|
|
|
|
|
|
async def test_wan_health_and_devices_use_the_shared_shapes(app):
|
|
wan = NS(is_up=False, wan_ip="203.0.113.7", latency_ms=250.0, rx_bytes_rate=2_000_000.0,
|
|
tx_bytes_rate=500_000.0, uptime_seconds=7200)
|
|
devices = [NS(name="switch", mac="aa", model="USW", device_type="usw", ip="10.0.0.2", state=1,
|
|
uptime_seconds=3600),
|
|
NS(name="ap-attic", mac="bb", model="U6", device_type="uap", ip="10.0.0.3", state=0,
|
|
uptime_seconds=None),
|
|
NS(name="ap-porch", mac="cc", model="U6", device_type="uap", ip="10.0.0.4", state=4,
|
|
uptime_seconds=None)]
|
|
async with app.test_request_context("/plugins/unifi/rows"):
|
|
page = await render_plugin_template(app, "unifi", "unifi/rows.html", latest_wan=wan, devices=devices,
|
|
device_state=device_state,
|
|
sparkline_latency="", sparkline_rx="", sparkline_tx="")
|
|
|
|
assert '<span class="stat-tile-label">WAN</span>' in page and "stat-crit" in page
|
|
assert '<span class="stat-tile-value">250 ms</span>' in page
|
|
assert 'class="dot dot-ok"' in page and 'class="dot dot-crit"' in page
|
|
# #5207: a device mid-upgrade is named, not drawn as down.
|
|
assert 'class="dot dot-warn" aria-hidden="true" title="Upgrading"' in page and "Offline" in page
|
|
assert "font-weight:600" not in page and "font-weight:700" not in page
|
|
assert not hex_colours(page), hex_colours(page)
|
|
|
|
|
|
async def test_event_categories_are_badges(app):
|
|
events = [NS(event_time=datetime(2026, 10, 6, 12, 0, tzinfo=timezone.utc), category="ids",
|
|
event_key="EVT_IPS_Alert", message="blocked", subsystem="ids")]
|
|
async with app.test_request_context("/plugins/unifi/events"):
|
|
page = await render_plugin_template(app, "unifi", "unifi/events.html", events=events)
|
|
assert '<span class="badge badge-crit">ids</span>' in page
|
|
assert "rgba(" not in page
|
|
|
|
|
|
def test_offline_devices_come_first_then_transitions_then_working():
|
|
devices = [NS(name=n, mac=n, state=st) for n, st in
|
|
[("b-ok", 1), ("a-ok", 1), ("upgrading", 4), ("gone", 0), ("odd", 99)]]
|
|
assert [d.name for d in devices_in_order(devices)] == ["gone", "odd", "upgrading", "a-ok", "b-ok"]
|
|
assert device_state(99) == ("unknown", "State 99")
|