Просмотр исходного кода

Fix ApiHealthSensor status comparison and attributes

ZiB 4 месяцев назад
Родитель
Сommit
3cdfec9a90
2 измененных файлов с 47 добавлено и 29 удалено
  1. 15 3
      custom_components/room_cal_ha/sensor.py
  2. 32 26
      tests/test_sensors.py

+ 15 - 3
custom_components/room_cal_ha/sensor.py

@@ -273,11 +273,23 @@ class ApiHealthSensor(CoordinatorEntity[RoomCalCoordinator], SensorEntity):
     api_status = self.coordinator.data.api_status
     if api_status is None:
       return None
-    return "OK" if api_status.status == "OK" else "Degraded"
+    return "OK" if api_status.status == "ok" else "Degraded"
 
   @property
   def extra_state_attributes(self) -> dict | None:
     api_status = self.coordinator.data.api_status
-    if api_status is None or not isinstance(api_status.services, dict) or not api_status.services:
+    if api_status is None:
       return None
-    return dict(api_status.services)
+    attrs: dict = {
+      "stale": api_status.stale,
+      "checked_at": api_status.checked_at.isoformat() if api_status.checked_at else None,
+    }
+    for key, val in api_status.checks.items():
+      if key == "credentials" and isinstance(val, dict):
+        for svc_key, svc_val in val.items():
+          attrs[svc_key] = svc_val.get("ok") if isinstance(svc_val, dict) else svc_val
+      elif isinstance(val, dict):
+        attrs[key] = val.get("ok")
+      else:
+        attrs[key] = val
+    return attrs

+ 32 - 26
tests/test_sensors.py

@@ -256,44 +256,50 @@ def _api_sensor(coordinator):
   return s
 
 
+_REAL_CHECKS = {
+  "caldav_connection": {"ok": True},
+  "calendar": {"ok": True},
+  "credentials": {
+    "airbnb": {"ok": True},
+    "booking": {"ok": False},
+  },
+}
+
+
 def test_api_health_ok():
-  status = ApiStatusData(status="OK", services={"booking": "OK", "calendar": "OK"})
-  coord = _coordinator(api_status=status)
-  s = _api_sensor(coord)
-  assert s.native_value == "OK"
+  status = ApiStatusData(status="ok", checks=_REAL_CHECKS)
+  assert _api_sensor(_coordinator(api_status=status)).native_value == "OK"
 
 
-def test_api_health_degraded_on_warn():
-  status = ApiStatusData(status="Warn", services={"booking": "Warn", "calendar": "OK"})
-  coord = _coordinator(api_status=status)
-  s = _api_sensor(coord)
-  assert s.native_value == "Degraded"
+def test_api_health_degraded_on_non_ok_status():
+  status = ApiStatusData(status="error", checks=_REAL_CHECKS)
+  assert _api_sensor(_coordinator(api_status=status)).native_value == "Degraded"
 
 
 def test_api_health_none_when_no_status():
-  coord = _coordinator(api_status=None)
-  s = _api_sensor(coord)
-  assert s.native_value is None
+  assert _api_sensor(_coordinator(api_status=None)).native_value is None
 
 
-def test_api_health_services_as_attributes():
-  svc = {"booking": "OK", "calendar": "Warn"}
-  status = ApiStatusData(status="Warn", services=svc)
-  coord = _coordinator(api_status=status)
-  s = _api_sensor(coord)
-  assert s.extra_state_attributes == svc
+def test_api_health_attrs_flatten_checks():
+  from datetime import datetime
+  ts = datetime(2026, 6, 23, 8, 0, 0)
+  status = ApiStatusData(status="ok", checks=_REAL_CHECKS, stale=False, checked_at=ts)
+  attrs = _api_sensor(_coordinator(api_status=status)).extra_state_attributes
+  assert attrs["caldav_connection"] is True
+  assert attrs["calendar"] is True
+  assert attrs["airbnb"] is True
+  assert attrs["booking"] is False
+  assert attrs["stale"] is False
+  assert attrs["checked_at"] == ts.isoformat()
 
 
-def test_api_health_no_attrs_when_services_empty():
-  status = ApiStatusData(status="OK", services={})
-  coord = _coordinator(api_status=status)
-  s = _api_sensor(coord)
-  assert s.extra_state_attributes is None
+def test_api_health_attrs_present_with_empty_checks():
+  status = ApiStatusData(status="ok", checks={}, stale=True)
+  attrs = _api_sensor(_coordinator(api_status=status)).extra_state_attributes
+  assert attrs == {"stale": True, "checked_at": None}
 
 
 def test_api_health_no_attrs_when_no_status():
-  coord = _coordinator(api_status=None)
-  s = _api_sensor(coord)
-  assert s.extra_state_attributes is None
+  assert _api_sensor(_coordinator(api_status=None)).extra_state_attributes is None