ha(H4): исправления по ревью — маскировка ключа в дампе, reload-repair, reconfigure сохраняет поля

- major: diagnostics больше не содержит полный lanip_key (esp_home —
  маска, entry_data redacted); ключ для ESPHome — через reconfigure/CLI;
  план §3 синхронизирован; дамп при незагруженной записи не падает
- reconfigure: сохраняет listen_port/keepalive_ms и текущие overrides/
  temp_step; превью-дефолты подхватывают значения записи
- repair fix-flow: подтверждение перезагружает запись (issue снимается
  только когда сессия вышла из key_error; иначе создаётся заново)
- key_issue_id helper, использование async_remove_issue (мёртвый код),
  CONF_EMAIL/PASSWORD в TO_REDACT, placeholders в fix_flow, тест
  плейсхолдеров ru
- тесты обновлены (47 components)
This commit is contained in:
2026-09-29 14:29:36 +03:00
parent dcbf9a6c7e
commit 43d3ff7dea
12 changed files with 160 additions and 80 deletions
@@ -3,6 +3,7 @@ from __future__ import annotations
import json
import pathlib
import re
ROOT = pathlib.Path(__file__).resolve().parents[3]
COMPONENT = ROOT / "custom_components" / "fglair"
@@ -27,3 +28,19 @@ def test_ru_covers_all_keys():
strings = json.loads((COMPONENT / "strings.json").read_text())
russian = json.loads((COMPONENT / "translations" / "ru.json").read_text())
assert _keys(strings) == _keys(russian)
def _placeholders(node, prefix: str = "") -> dict[str, set[str]]:
out: dict[str, set[str]] = {}
if isinstance(node, dict):
for key, value in node.items():
out.update(_placeholders(value, prefix + key + "."))
elif isinstance(node, str):
out[prefix] = set(re.findall(r"{(\w+)}", node))
return out
def test_ru_placeholders_match():
strings = json.loads((COMPONENT / "strings.json").read_text())
russian = json.loads((COMPONENT / "translations" / "ru.json").read_text())
assert _placeholders(strings) == _placeholders(russian)