Skip to content

Commit 46359b9

Browse files
committed
fix: lowercase the selector option keys for hassfest, keep the stored value
Hassfest rejects translation keys that are not [a-z0-9-_]+, and the protocol selector used the option values as keys — one of which is XMPP, uppercase because it comes from bosch_thermostat_client.const. The selector now emits "xmpp" and the step maps it back to XMPP before storing. entry.data[CONF_PROTOCOL] keeps the exact value it has always held, so existing entries still match and no migration is needed. Pinned that invariant with a test, since it is the kind of thing a future rename would quietly break.
1 parent 3d0ed9e commit 46359b9

10 files changed

Lines changed: 33 additions & 19 deletions

File tree

custom_components/bosch/config_flow.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,10 @@ async def async_step_easycontrol_protocol(self, user_input=None):
7070
"""Handle EasyControl protocol choice: XMPP or POINTTAPI."""
7171
errors = {}
7272
if user_input is not None:
73-
self._protocol = user_input[CONF_PROTOCOL]
73+
# The selector's option values are the translation keys, which
74+
# hassfest requires to be lowercase — but XMPP is stored uppercase
75+
# in entry.data, so map rather than change what is persisted.
76+
self._protocol = XMPP if user_input[CONF_PROTOCOL] == "xmpp" else POINTTAPI
7477
if self._protocol == XMPP:
7578
return self._show_xmpp_form(errors)
7679
# OAuth-first: the authorize URL is device-independent, and the
@@ -82,7 +85,7 @@ async def async_step_easycontrol_protocol(self, user_input=None):
8285
{
8386
vol.Required(CONF_PROTOCOL): SelectSelector(
8487
SelectSelectorConfig(
85-
options=[XMPP, POINTTAPI],
88+
options=["xmpp", POINTTAPI],
8689
mode=SelectSelectorMode.LIST,
8790
translation_key="protocol",
8891
)

custom_components/bosch/strings.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -508,8 +508,8 @@
508508
"selector": {
509509
"protocol": {
510510
"options": {
511-
"XMPP": "Local connection (XMPP)",
512-
"pointtapi": "Cloud / Bosch account"
511+
"pointtapi": "Cloud / Bosch account",
512+
"xmpp": "Local connection (XMPP)"
513513
}
514514
}
515515
}

custom_components/bosch/translations/de.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -487,8 +487,8 @@
487487
"selector": {
488488
"protocol": {
489489
"options": {
490-
"XMPP": "Lokale Verbindung (XMPP)",
491-
"pointtapi": "Cloud / Bosch-Konto"
490+
"pointtapi": "Cloud / Bosch-Konto",
491+
"xmpp": "Lokale Verbindung (XMPP)"
492492
}
493493
}
494494
}

custom_components/bosch/translations/en.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -508,8 +508,8 @@
508508
"selector": {
509509
"protocol": {
510510
"options": {
511-
"XMPP": "Local connection (XMPP)",
512-
"pointtapi": "Cloud / Bosch account"
511+
"pointtapi": "Cloud / Bosch account",
512+
"xmpp": "Local connection (XMPP)"
513513
}
514514
}
515515
}

custom_components/bosch/translations/fr.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -487,8 +487,8 @@
487487
"selector": {
488488
"protocol": {
489489
"options": {
490-
"XMPP": "Connexion locale (XMPP)",
491-
"pointtapi": "Cloud / compte Bosch"
490+
"pointtapi": "Cloud / compte Bosch",
491+
"xmpp": "Connexion locale (XMPP)"
492492
}
493493
}
494494
}

custom_components/bosch/translations/it.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -487,8 +487,8 @@
487487
"selector": {
488488
"protocol": {
489489
"options": {
490-
"XMPP": "Connessione locale (XMPP)",
491-
"pointtapi": "Cloud / account Bosch"
490+
"pointtapi": "Cloud / account Bosch",
491+
"xmpp": "Connessione locale (XMPP)"
492492
}
493493
}
494494
}

custom_components/bosch/translations/nl.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -487,8 +487,8 @@
487487
"selector": {
488488
"protocol": {
489489
"options": {
490-
"XMPP": "Lokale verbinding (XMPP)",
491-
"pointtapi": "Cloud / Bosch-account"
490+
"pointtapi": "Cloud / Bosch-account",
491+
"xmpp": "Lokale verbinding (XMPP)"
492492
}
493493
}
494494
}

custom_components/bosch/translations/pl.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -487,8 +487,8 @@
487487
"selector": {
488488
"protocol": {
489489
"options": {
490-
"XMPP": "Połączenie lokalne (XMPP)",
491-
"pointtapi": "Chmura / konto Bosch"
490+
"pointtapi": "Chmura / konto Bosch",
491+
"xmpp": "Połączenie lokalne (XMPP)"
492492
}
493493
}
494494
}

custom_components/bosch/translations/sk.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -487,8 +487,8 @@
487487
"selector": {
488488
"protocol": {
489489
"options": {
490-
"XMPP": "Lokálne pripojenie (XMPP)",
491-
"pointtapi": "Cloud / účet Bosch"
490+
"pointtapi": "Cloud / účet Bosch",
491+
"xmpp": "Lokálne pripojenie (XMPP)"
492492
}
493493
}
494494
}

unittests/test_config_flow.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,23 @@ async def test_xmpp_protocol_shows_xmpp_config(mock_hass):
5959
flow = _make_flow(mock_hass)
6060
flow._choose_type = "EASYCONTROL"
6161
result = await flow.async_step_easycontrol_protocol(
62-
{CONF_PROTOCOL: "XMPP"}
62+
{CONF_PROTOCOL: "xmpp"}
6363
)
6464
assert result["type"] == "form"
6565
assert result["step_id"] == "xmpp_config"
6666

6767

68+
@pytest.mark.asyncio
69+
async def test_selector_value_is_lowercase_but_stored_protocol_is_not(mock_hass):
70+
"""hassfest requires lowercase translation keys, so the selector emits
71+
"xmpp" — but entry.data has always held "XMPP" and existing entries are
72+
matched against it, so the stored value must not change."""
73+
flow = _make_flow(mock_hass)
74+
flow._choose_type = "EASYCONTROL"
75+
await flow.async_step_easycontrol_protocol({CONF_PROTOCOL: "xmpp"})
76+
assert flow._protocol == "XMPP"
77+
78+
6879
def _prime_tokens(flow):
6980
"""Give a flow OAuth tokens + entry-creation mocks (post-OAuth state)."""
7081
flow._tokens = {

0 commit comments

Comments
 (0)