ha(ux): исправления по ревью — быстрый выход пробинга, prefill шаблона, ниты

- major: probe_template прекращает перебор на unreachable/no_slots/key_error
  (недоступный модуль: ~10 c вместо ~49 c), продолжает только при
  properties_missing (доступен, но чужой шаблон); +тест
- m1: extra_state_attributes не падает до добавления в hass
- m2: reconfigure берёт сохранённый шаблон как дефолт (не пересчитывает по
  модели); +тест
- m3: device_capabilities/display_temperature переведены в необязательные
  зонды (trial не падает на молчащем caps; feature-модель трактует None
  как «не режем»)
- m4: async_sync_now(online_timeout) — честное имя/докстринг
- ниты: удалены PRESET_CAP/as_dict/лишние плейсхолдеры, DIRECTION_KEYS
  упрощён, тавтология в тесте исправлена, en-тире
- 59 components + 47 pyfglair/acceptance зелёные
This commit is contained in:
2026-09-29 18:02:52 +03:00
parent d1c02d7c4b
commit 976a2dcbb8
8 changed files with 76 additions and 29 deletions
+19 -3
View File
@@ -60,9 +60,8 @@ def test_resolve_and_featureset_override():
resolved = resolve_features(values, set(), {"swing_vertical": True})
assert resolved["swing_vertical"] is True
assert resolved["powerful_mode"] is False
assert len(resolved) == len(
{key for key in resolved}
)
from custom_components.fglair.const import FEATURES
assert len(resolved) == len(FEATURES)
feature_set = FeatureSet({"swing_vertical": True}, values)
assert feature_set.enabled("swing_vertical") is True
assert feature_set.enabled("powerful_mode") is False
@@ -103,3 +102,20 @@ def test_resolved_features_for_ap_wc1e_without_sensor():
assert resolved["mode_cool"] is True
assert resolved["economy_mode"] is True
assert resolved["powerful_mode"] is False
def test_probe_stops_on_unreachable(monkeypatch):
"""Недоступный модуль не перебираем трижды — выходим после первой сессии."""
from custom_components.fglair import trial as tr
calls: list = []
def fake_trial(*args, **kwargs):
calls.append(kwargs.get("template"))
return tr.TrialResult(ok=False, reason="unreachable")
monkeypatch.setattr(tr, "trial_connect", fake_trial)
template, props = tr.probe_template("host", "dsn", "key", 1)
assert template is None
assert props == {}
assert calls == [Template.A]