Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions custom_components/uk_bin_collection/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,11 @@ async def async_step_user(self, user_input: Optional[Dict[str, Any]] = None):
{
vol.Required("name"): cv.string,
vol.Required("council"): vol.In(self.council_options),
# NOTE: defaulting manual_refresh_only to True means new
# installs get NO automatic refresh unless the user unticks
# this box. Given the "entities only update on restart"
# reports (e.g. #2193), this default is questionable and
# should be revisited separately (kept as-is for this PR).
vol.Optional("manual_refresh_only", default=True): bool,
vol.Optional("icon_color_mapping", default=""): cv.string,
}
Expand Down
10 changes: 8 additions & 2 deletions custom_components/uk_bin_collection/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@
"data": {
"name": "Location name",
"council": "Council",
"manual_refresh_only":"Automatically refresh the sensor",
"manual_refresh_only": "Manual refresh only (disable automatic updates — refresh via the uk_bin_collection.manual_refresh service)",
"icon_color_mapping": "JSON to map Bin Type for Colour and Icon (see documentation)"
},
"data_description": {
"manual_refresh_only": "When ticked, the integration will NOT refresh automatically — data is only fetched at setup and when you call the uk_bin_collection.manual_refresh service. When unticked, data refreshes every 'update_interval' hours."
},
"description": "Please see the documentation if your council isn't listed"
},
"council": {
Expand Down Expand Up @@ -42,10 +45,13 @@
"web_driver": "To run on a remote Selenium Server add the Selenium Server URL",
"headless": "Run Selenium in headless mode (recommended)",
"local_browser": "Don't run on remote Selenium server, use local install of Chrome instead",
"manual_refresh_only":"Automatically refresh the sensor",
"manual_refresh_only": "Manual refresh only (disable automatic updates — refresh via the uk_bin_collection.manual_refresh service)",
"icon_color_mapping": "JSON to map Bin Type for Colour and Icon (see documentation)",
"submit": "Submit"
},
"data_description": {
"manual_refresh_only": "When ticked, the integration will NOT refresh automatically — data is only fetched at setup and when you call the uk_bin_collection.manual_refresh service. When unticked, data refreshes every 'update_interval' hours."
},
"description": "Please refer to your council's wiki entry for details on what to enter."
}
},
Expand Down
113 changes: 113 additions & 0 deletions custom_components/uk_bin_collection/tests/test_translations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
"""Regression tests for the config-flow translation strings.

These guard against the `manual_refresh_only` label inversion (issue #2193):
the field stores "manual refresh only" semantics, but the UI used to label it
"Automatically refresh the sensor" — the exact inverse — so ticking the box
silently disabled automatic refresh.

Dependency-free on purpose: json + pathlib only.
"""

import json
from pathlib import Path

# custom_components/uk_bin_collection/
INTEGRATION_DIR = Path(__file__).resolve().parent.parent
STRINGS_JSON = INTEGRATION_DIR / "strings.json"
TRANSLATIONS_DIR = INTEGRATION_DIR / "translations"

KEY = "manual_refresh_only"
OLD_INVERTED_LABEL = "Automatically refresh the sensor"


def _load(path: Path) -> dict:
with path.open(encoding="utf-8") as handle:
return json.load(handle)


def _all_translation_files() -> list[Path]:
return sorted(TRANSLATIONS_DIR.glob("*.json"))


def _steps_with_key(data: dict) -> dict:
"""Return {step_name: label} for every config.step.*.data carrying KEY."""
found = {}
steps = data.get("config", {}).get("step", {})
for step_name, step in steps.items():
step_data = step.get("data", {})
if KEY in step_data:
found[step_name] = step_data[KEY]
return found


def _steps_with_description(data: dict) -> dict:
"""Return {step_name: text} for every config.step.*.data_description[KEY]."""
found = {}
steps = data.get("config", {}).get("step", {})
for step_name, step in steps.items():
descriptions = step.get("data_description", {})
if KEY in descriptions:
found[step_name] = descriptions[KEY]
return found


def test_all_json_files_are_valid():
"""Every strings/translation file must parse as JSON."""
_load(STRINGS_JSON)
for path in _all_translation_files():
_load(path)


def test_manual_refresh_label_not_inverted():
"""No label may claim the field enables automatic refresh."""
files = [STRINGS_JSON, *_all_translation_files()]
for path in files:
labels = _steps_with_key(_load(path))
assert labels, f"{path.name}: expected at least one '{KEY}' label"
for step_name, label in labels.items():
where = f"{path.name} :: config.step.{step_name}.data.{KEY}"

# The exact old inverted English string must be gone everywhere.
assert label != OLD_INVERTED_LABEL, (
f"{where}: still uses the inverted label {OLD_INVERTED_LABEL!r}"
)

# If the label mentions "automatic(ally)", it must be a negation
# (e.g. "disable automatic updates"), never a promise to refresh.
lowered = label.lower()
if "automatic" in lowered:
assert "manual" in lowered or "disable" in lowered, (
f"{where}: label {label!r} mentions 'automatic' without a "
"negating 'manual'/'disable' — likely still inverted"
)


def test_strings_and_en_translation_stay_in_sync():
"""strings.json and en.json must carry KEY in the same steps."""
strings_steps = set(_steps_with_key(_load(STRINGS_JSON)))
en_steps = set(_steps_with_key(_load(TRANSLATIONS_DIR / "en.json")))
assert strings_steps == en_steps, (
f"strings.json steps {sorted(strings_steps)} != "
f"en.json steps {sorted(en_steps)}"
)
# Guard against the key silently disappearing from both.
assert strings_steps, "manual_refresh_only missing from strings.json steps"


def test_manual_refresh_has_description_in_every_locale():
"""Every locale must carry data_description for KEY in each step that
labels it, so no locale falls back to English helper text."""
files = [STRINGS_JSON, *_all_translation_files()]
for path in files:
data = _load(path)
label_steps = set(_steps_with_key(data))
description_steps = set(_steps_with_description(data))
assert label_steps, f"{path.name}: expected at least one '{KEY}' label"
missing = label_steps - description_steps
assert not missing, (
f"{path.name}: missing data_description.{KEY} in step(s) "
f"{sorted(missing)}"
)
for step_name, text in _steps_with_description(data).items():
where = f"{path.name} :: config.step.{step_name}.data_description.{KEY}"
assert text.strip(), f"{where}: description must not be empty"
10 changes: 8 additions & 2 deletions custom_components/uk_bin_collection/translations/cy.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@
"data": {
"name": "Enw'r lleoliad",
"council": "Cyngor",
"manual_refresh_only": "Adnewyddu'r synhwyrydd yn awtomatig",
"manual_refresh_only": "Adnewyddu â llaw yn unig (analluogi diweddariadau awtomatig — adnewyddwch drwy'r gwasanaeth uk_bin_collection.manual_refresh)",
Comment thread
pacso marked this conversation as resolved.
"icon_color_mapping": "JSON i fapio Math y Bin ar gyfer Lliw ac Eicon gweler: https://github.com/robbrad/UKBinCollectionData"
},
"data_description": {
"manual_refresh_only": "Pan fydd wedi'i dicio, NI fydd yr integreiddiad yn adnewyddu'n awtomatig — dim ond wrth osod a phan fyddwch yn galw'r gwasanaeth uk_bin_collection.manual_refresh y caiff data ei nôl. Pan na fydd wedi'i dicio, caiff data ei adnewyddu bob 'update_interval' awr."
},
"description": "Gweler [yma](https://github.com/robbrad/UKBinCollectionData#requesting-your-council) os nad yw eich cyngor wedi'i restru"
},
"council": {
Expand Down Expand Up @@ -41,11 +44,14 @@
"usrn": "USRN (Rhif Cyfeirnod Stryd Unigryw)",
"web_driver": "I redeg ar weinydd Selenium o bell, ychwanegwch URL y Weinydd Selenium",
"headless": "Rhedeg Selenium yn y modd heb ben (argymhellir)",
"manual_refresh_only": "Adnewyddu'r synhwyrydd yn awtomatig",
"manual_refresh_only": "Adnewyddu â llaw yn unig (analluogi diweddariadau awtomatig — adnewyddwch drwy'r gwasanaeth uk_bin_collection.manual_refresh)",
"local_browser": "Peidiwch â rhedeg ar weinydd Selenium o bell, defnyddiwch osodiad lleol o Chrome yn lle",
"icon_color_mapping": "JSON i fapio Math y Bin ar gyfer Lliw ac Eicon gweler: https://github.com/robbrad/UKBinCollectionData",
"submit": "Cyflwyno"
},
"data_description": {
"manual_refresh_only": "Pan fydd wedi'i dicio, NI fydd yr integreiddiad yn adnewyddu'n awtomatig — dim ond wrth osod a phan fyddwch yn galw'r gwasanaeth uk_bin_collection.manual_refresh y caiff data ei nôl. Pan na fydd wedi'i dicio, caiff data ei adnewyddu bob 'update_interval' awr."
},
"description": "Cyfeiriwch at gofnod [wiki](https://github.com/robbrad/UKBinCollectionData/wiki/Councils) eich cyngor am fanylion ar beth i'w nodi."
}
},
Expand Down
10 changes: 8 additions & 2 deletions custom_components/uk_bin_collection/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@
"data": {
"name": "Location name",
"council": "Council",
"manual_refresh_only":"Automatically refresh the sensor",
"manual_refresh_only": "Manual refresh only (disable automatic updates — refresh via the uk_bin_collection.manual_refresh service)",
"icon_color_mapping": "JSON to map Bin Type for Colour and Icon (see documentation)"
},
"data_description": {
"manual_refresh_only": "When ticked, the integration will NOT refresh automatically — data is only fetched at setup and when you call the uk_bin_collection.manual_refresh service. When unticked, data refreshes every 'update_interval' hours."
},
"description": "Please see the documentation if your council isn't listed"
},
"council": {
Expand Down Expand Up @@ -42,10 +45,13 @@
"web_driver": "To run on a remote Selenium Server add the Selenium Server URL",
"headless": "Run Selenium in headless mode (recommended)",
"local_browser": "Don't run on remote Selenium server, use local install of Chrome instead",
"manual_refresh_only":"Automatically refresh the sensor",
"manual_refresh_only": "Manual refresh only (disable automatic updates — refresh via the uk_bin_collection.manual_refresh service)",
"icon_color_mapping": "JSON to map Bin Type for Colour and Icon (see documentation)",
"submit": "Submit"
},
"data_description": {
"manual_refresh_only": "When ticked, the integration will NOT refresh automatically — data is only fetched at setup and when you call the uk_bin_collection.manual_refresh service. When unticked, data refreshes every 'update_interval' hours."
},
"description": "Please refer to your council's wiki entry for details on what to enter."
}
},
Expand Down
10 changes: 8 additions & 2 deletions custom_components/uk_bin_collection/translations/ga.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@
"data": {
"name": "Ainm Suíomh",
"council": "Comhairle",
"manual_refresh_only": "Athnuaigh an braiteoir go huathoibríoch",
"manual_refresh_only": "Athnuachan de láimh amháin (díchumasaigh nuashonruithe uathoibríocha — athnuaigh tríd an tseirbhís uk_bin_collection.manual_refresh)",
"icon_color_mapping": "JSON chun Cineál Bin a mhapáil do Dath agus Deilbhín féach: https://github.com/robbrad/UKBinCollectionData"
},
"data_description": {
"manual_refresh_only": "Nuair a bhíonn sé ticeáilte, NÍ dhéanfaidh an chomhtháthú athnuachan go huathoibríoch — ní fhaightear sonraí ach ag am socraithe agus nuair a ghlaonn tú ar an tseirbhís uk_bin_collection.manual_refresh. Nuair nach mbíonn sé ticeáilte, déantar sonraí a athnuachan gach 'update_interval' uair."
},
"description": "Féach [anseo](https://github.com/robbrad/UKBinCollectionData#requesting-your-council) mura bhfuil do chomhairle liostaithe"
},
"council": {
Expand Down Expand Up @@ -42,10 +45,13 @@
"web_driver": "Chun rith ar Fhreastalaí Iargúlta Selenium cuir isteach URL an Fhreastalaí Selenium",
"headless": "Rith Selenium i mód gan cheann (molta)",
"local_browser": "Ná rith ar fhreastalaí iargúlta Selenium, úsáid suiteáil áitiúil de Chrome ina ionad",
"manual_refresh_only": "Athnuaigh an braiteoir go huathoibríoch",
"manual_refresh_only": "Athnuachan de láimh amháin (díchumasaigh nuashonruithe uathoibríocha — athnuaigh tríd an tseirbhís uk_bin_collection.manual_refresh)",
"icon_color_mapping": "JSON chun Cineál Bin a mhapáil do Dath agus Deilbhín féach: https://github.com/robbrad/UKBinCollectionData",
"submit": "Cuir isteach"
},
"data_description": {
"manual_refresh_only": "Nuair a bhíonn sé ticeáilte, NÍ dhéanfaidh an chomhtháthú athnuachan go huathoibríoch — ní fhaightear sonraí ach ag am socraithe agus nuair a ghlaonn tú ar an tseirbhís uk_bin_collection.manual_refresh. Nuair nach mbíonn sé ticeáilte, déantar sonraí a athnuachan gach 'update_interval' uair."
},
"description": "Féach ar iontráil [wiki](https://github.com/robbrad/UKBinCollectionData/wiki/Councils) do chomhairle le haghaidh sonraí ar cad atá le cur isteach."
}
},
Expand Down
10 changes: 8 additions & 2 deletions custom_components/uk_bin_collection/translations/gd.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@
"data": {
"name": "Ainm Àite",
"council": "Comhairle",
"manual_refresh_only": "Ùraich an sensor gu fèin-obrachail",
"manual_refresh_only": "Ùrachadh le làimh a-mhàin (cuir à comas ùrachaidhean fèin-obrachail — ùraich tron t-seirbheis uk_bin_collection.manual_refresh)",
"local_browser": "Na ruith air frithealaiche Selenium iomallach, cleachd stàladh ionadail de Chrome an àite",
"icon_color_mapping": "JSON gus Seòrsa Biona a mhapadh airson Dath agus Ìomhaigh faic: https://github.com/robbrad/UKBinCollectionData"
},
"data_description": {
"manual_refresh_only": "Nuair a tha e air a chomharrachadh, CHA dèan an t-amalachadh ùrachadh gu fèin-obrachail — cha tèid dàta fhaighinn ach aig àm suidheachaidh agus nuair a ghairmeas tu an t-seirbheis uk_bin_collection.manual_refresh. Nuair nach eil e air a chomharrachadh, thèid dàta ùrachadh gach 'update_interval' uair."
},
"description": "Feuch an toir thu sùil [an seo](https://github.com/robbrad/UKBinCollectionData#requesting-your-council) mura h-eil do chomhairle air a liostadh"
},
"council": {
Expand Down Expand Up @@ -42,11 +45,14 @@
"usrn": "USRN (Àireamh Iomraidh Sràid Aonraic)",
"web_driver": "Gus ruith air Frithealaiche Selenium iomallach cuir a-steach an URL Frithealaiche Selenium",
"headless": "Ruith Selenium ann am modh gun cheann (air a mholadh)",
"manual_refresh_only": "Ùraich an sensor gu fèin-obrachail",
"manual_refresh_only": "Ùrachadh le làimh a-mhàin (cuir à comas ùrachaidhean fèin-obrachail — ùraich tron t-seirbheis uk_bin_collection.manual_refresh)",
"local_browser": "Na ruith air frithealaiche Selenium iomallach, cleachd stàladh ionadail de Chrome an àite",
"icon_color_mapping": "JSON gus Seòrsa Biona a mhapadh airson Dath agus Ìomhaigh faic: https://github.com/robbrad/UKBinCollectionData",
"submit": "Cuir a-steach"
},
"data_description": {
"manual_refresh_only": "Nuair a tha e air a chomharrachadh, CHA dèan an t-amalachadh ùrachadh gu fèin-obrachail — cha tèid dàta fhaighinn ach aig àm suidheachaidh agus nuair a ghairmeas tu an t-seirbheis uk_bin_collection.manual_refresh. Nuair nach eil e air a chomharrachadh, thèid dàta ùrachadh gach 'update_interval' uair."
},
"description": "Feuch an toir thu sùil air inntrigeadh [wiki](https://github.com/robbrad/UKBinCollectionData/wiki/Councils) na comhairle agad airson mion-fhiosrachadh air dè a chur a-steach."
}
},
Expand Down
Loading
Loading