M5: roll Energy chart window for live auto-refresh (English label); render boolean config fields as switches

This commit is contained in:
2026-06-22 19:40:18 +02:00
parent 935e68846c
commit 75d685f04d
10 changed files with 468 additions and 30 deletions
+99
View File
@@ -557,3 +557,102 @@ def test_put_config_invalid_mqtt_port_returns_422_and_does_not_write(
conn.close()
assert rows.get("MQTT_BROKER_PORT") != "not-a-number"
# ---------------------------------------------------------------------------
# M5-polish2 Area B: bool fields have input_type="checkbox"
# ---------------------------------------------------------------------------
EXPECTED_CHECKBOX_FIELDS = {
"APP_DEBUG",
"SMTP_ENABLED",
"SMTP_USE_STARTTLS",
"AUTH_LOGIN_THROTTLE_ENABLED",
"MQTT_ENABLED",
"MQTT_TLS_ENABLED",
"HA_DISCOVERY_ENABLED",
"MODBUS_POLLING_ENABLED",
}
def test_bool_fields_have_checkbox_input_type(client: TestClient) -> None:
"""All pure-bool config fields must return input_type='checkbox' from GET /api/config."""
_login(client)
response = client.get("/api/config")
assert response.status_code == 200
body = response.json()
all_fields = {
field["env_name"]: field
for section in body["sections"]
for field in section["fields"]
}
for env_name in EXPECTED_CHECKBOX_FIELDS:
assert env_name in all_fields, f"{env_name} not found in config response"
actual_type = all_fields[env_name]["input_type"]
assert actual_type == "checkbox", (
f"{env_name}: expected input_type='checkbox', got {actual_type!r}"
)
def test_auth_cookie_secure_override_is_not_checkbox(client: TestClient) -> None:
"""AUTH_COOKIE_SECURE_OVERRIDE is bool|None (three-state) and must NOT be checkbox."""
_login(client)
response = client.get("/api/config")
assert response.status_code == 200
body = response.json()
all_fields = {
field["env_name"]: field
for section in body["sections"]
for field in section["fields"]
}
# This field is present in CONFIG_FIELDS; its type is bool|None so it stays text.
if "AUTH_COOKIE_SECURE_OVERRIDE" in all_fields:
actual_type = all_fields["AUTH_COOKIE_SECURE_OVERRIDE"]["input_type"]
assert actual_type != "checkbox", (
f"AUTH_COOKIE_SECURE_OVERRIDE should not be checkbox (it is bool|None); got {actual_type!r}"
)
def test_put_config_bool_field_roundtrip_true_false(
client: TestClient, test_database_urls
) -> None:
"""Saving 'true'/'false' string for a bool checkbox field roundtrips correctly."""
_login(client)
# Set MQTT_ENABLED to 'true' via config PUT
payload_true = _full_config_payload({"MQTT_ENABLED": "true"})
resp_true = client.put(
"/api/config",
json={"updates": payload_true},
headers={"X-CSRF-Token": "token"},
)
assert resp_true.status_code == 200
conn = sqlite3.connect(test_database_urls["app_path"])
try:
rows = dict(conn.execute("SELECT key, value FROM app_config").fetchall())
finally:
conn.close()
assert rows.get("MQTT_ENABLED") == "true"
# Now set to 'false'
payload_false = _full_config_payload({"MQTT_ENABLED": "false"})
resp_false = client.put(
"/api/config",
json={"updates": payload_false},
headers={"X-CSRF-Token": "token"},
)
assert resp_false.status_code == 200
conn = sqlite3.connect(test_database_urls["app_path"])
try:
rows = dict(conn.execute("SELECT key, value FROM app_config").fetchall())
finally:
conn.close()
assert rows.get("MQTT_ENABLED") == "false"