Skip to content

Commit 0f8287a

Browse files
fix: clarify the addon-not-back error message (#2132)
* fix: clarify the addon-not-back error message Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NgWpy7arov56hET1PzoeCS * fix: gate the live-tree no-op invariant and align the JS fallback wording The canary flushed out one more ungated live-tree assertion: test_clean_tree_plans_no_work asserts build_plan() over the real repo returns no work, which any English-changing PR legitimately violates until the sync runs. Gated behind LOCALE_COMPLETENESS_CHECKS and run in the workflow's verification as the sync's own no-op invariant (a third pytest invocation with the same junit skip assertion; the shape test now scans the file's marker and filter names). Bot review round: settings.js's inline fallback for errors.addon_not_back still carried the clipped wording (CodeRabbit), and the restart-probe behavior test only pinned the first sentence (Codex) — both now match the corrected string. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NgWpy7arov56hET1PzoeCS --------- Co-authored-by: kingpanther13 <kingpanther13@users.noreply.github.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1 parent 01f9bff commit 0f8287a

6 files changed

Lines changed: 28 additions & 11 deletions

File tree

.github/workflows/locale-sync.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,8 +218,14 @@ jobs:
218218
uv run pytest tests/src/unit/test_settings_ui_i18n.py -q --maxfail=0 \
219219
-k "test_shipped_catalog_translates_the_tools_tab" \
220220
--junitxml="$RUNNER_TEMP/verify-i18n.xml"
221+
# The sync's own no-op invariant: a rerun against the tree this run
222+
# just translated and repinned must plan zero work.
223+
uv run pytest tests/src/unit/test_translate_locales.py -q --maxfail=0 \
224+
-k "test_clean_tree_plans_no_work" \
225+
--junitxml="$RUNNER_TEMP/verify-noop.xml"
221226
assert_nothing_skipped "$RUNNER_TEMP/verify-parity.xml"
222227
assert_nothing_skipped "$RUNNER_TEMP/verify-i18n.xml"
228+
assert_nothing_skipped "$RUNNER_TEMP/verify-noop.xml"
223229
224230
- name: Check for held English-source staleness
225231
id: staleness

src/ha_mcp/settings_ui/locales/en.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@
184184
"errors.stop_failed": "Stop failed",
185185
"errors.restart_failed": "Restart failed",
186186
"errors.failed_detail": "Failed: {detail}",
187-
"errors.addon_not_back": "App (add-on) did not come back online. Reload manually",
187+
"errors.addon_not_back": "App (add-on) did not come back online. Reload the page manually.",
188188
"errors.unparseable_suffix": " (response body unparseable)",
189189
"common.operation_failed": "{operation} failed: {detail}",
190190
"common.enabled": "enabled",

src/ha_mcp/settings_ui/settings.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -648,7 +648,7 @@ async function _runRestartReloadCycle(previousInstanceId) {
648648
// never actually fired (silent supervisor failure → instance_id
649649
// never flipped) OR supervisor is genuinely slower than the cap.
650650
// Surface a clear next-step instead of silently doing nothing.
651-
btn.textContent = t('errors.addon_not_back', {}, 'App (add-on) did not come back online. Reload manually');
651+
btn.textContent = t('errors.addon_not_back', {}, 'App (add-on) did not come back online. Reload the page manually.');
652652
btn.disabled = false;
653653
restartInProgress = false;
654654
}

tests/src/unit/test_locale_sync_gate_shape.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
_GATED_TEST_FILES = (
2929
Path(__file__).with_name("test_locale_parity.py"),
3030
Path(__file__).with_name("test_settings_ui_i18n.py"),
31+
Path(__file__).with_name("test_translate_locales.py"),
3132
)
3233

3334

@@ -58,10 +59,7 @@ def _verification_steps() -> list[dict[str, Any]]:
5859
step
5960
for step in steps
6061
if "pytest" in str(step.get("run", ""))
61-
and (
62-
"test_locale_parity.py" in str(step.get("run", ""))
63-
or "test_settings_ui_i18n.py" in str(step.get("run", ""))
64-
)
62+
and any(path.name in str(step.get("run", "")) for path in _GATED_TEST_FILES)
6563
]
6664

6765

tests/src/unit/test_settings_ui_js_behavior.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -923,9 +923,9 @@ def test_probe_waits_for_instance_id_flip_not_just_200(
923923
"probe must not reload when instance_id never flips — "
924924
"that would land the user back on the same broken instance"
925925
)
926-
assert "did not come back online" in result.dom.lower(), (
927-
f"expected manual-reload fallback message, dom={result.dom[:600]}"
928-
)
926+
assert (
927+
"did not come back online. reload the page manually." in result.dom.lower()
928+
), f"expected manual-reload fallback message, dom={result.dom[:600]}"
929929

930930

931931
# ---------------------------------------------------------------------------

tests/src/unit/test_translate_locales.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from __future__ import annotations
1313

1414
import json
15+
import os
1516
import sys
1617
from pathlib import Path
1718
from types import SimpleNamespace
@@ -479,9 +480,21 @@ def dead_engine(prompt: str) -> dict[str, str]:
479480
"engine calls"
480481
)
481482

483+
# Same gate as ``test_locale_parity.completeness`` (see the marker
484+
# comment there): this asserts the LIVE tree owes no translations, which
485+
# any PR that changes an English string legitimately violates until the
486+
# post-merge sync runs. ``test_locale_sync_gate_shape`` pins the wiring.
487+
@pytest.mark.skipif(
488+
not os.environ.get("LOCALE_COMPLETENESS_CHECKS"),
489+
reason=(
490+
"translated-catalog completeness is verified by the post-merge "
491+
"locale-sync workflow — set LOCALE_COMPLETENESS_CHECKS=1 to run"
492+
),
493+
)
482494
def test_clean_tree_plans_no_work(self) -> None:
483-
"""The no-op invariant the CI loop terminates on: after a translation
484-
commit repins the baseline, the retriggered run must find nothing."""
495+
"""The sync's own no-op invariant: after a run repins the baseline,
496+
a rerun must find nothing — verified in the workflow, where it runs
497+
against the freshly translated tree."""
485498
module = translate_locales._load_test_module()
486499
plan = translate_locales.build_plan(module)
487500
assert plan.items == []

0 commit comments

Comments
 (0)