Files
hermes-webui/tests/test_vietnamese_locale.py
nesquena-hermes 30fb4edc1f fix(i18n): stop double-rendering the skip-all lightning icon (#7701)
The approval card's Skip-all button drew its icon twice: once from the
.approval-btn-icon span in static/index.html and again from the leading
glyph baked into the approval_skip_all translation in 14 of 15 locales.
pt already shipped without the prefix, which is the correct shape.

Strip the glyph from every locale value so the markup span is the single
icon source, matching Allow once / Allow session / Always allow / Deny,
which all pair an icon element with a glyph-free label.

test_vietnamese_locale.py asserted the old prefixed string verbatim; its
expectation is updated to the corrected value.
2026-09-22 06:17:58 +00:00

118 lines
3.5 KiB
Python

from collections import Counter
from pathlib import Path
import re
from tests.test_issue2147_profile_concept_help import PROFILE_CONCEPT_KEYS
REPO = Path(__file__).resolve().parent.parent
PROFILE_CONCEPT_FALLBACK_KEYS = {
*PROFILE_CONCEPT_KEYS,
"workspace_artifact_source_session",
}
def read(path: Path) -> str:
return path.read_text(encoding="utf-8")
def test_vietnamese_locale_block_exists():
src = read(REPO / "static" / "i18n.js")
assert "\n _lang: 'vi'," in src
assert "_label: 'Tiếng Việt'" in src
assert "_speech: 'vi-VN'" in src
def extract_locale_block(src: str, locale_key: str) -> str:
start_match = re.search(rf"\b{re.escape(locale_key)}\s*:\s*\{{", src)
assert start_match, f"{locale_key} locale block not found"
brace_start = start_match.end() - 1
depth = 0
in_single = False
in_double = False
in_backtick = False
escape = False
for i in range(brace_start, len(src)):
ch = src[i]
if escape:
escape = False
continue
if in_single:
if ch == "\\":
escape = True
elif ch == "'":
in_single = False
continue
if in_double:
if ch == "\\":
escape = True
elif ch == '"':
in_double = False
continue
if in_backtick:
if ch == "\\":
escape = True
elif ch == "`":
in_backtick = False
continue
if ch == "'":
in_single = True
continue
if ch == '"':
in_double = True
continue
if ch == "`":
in_backtick = True
continue
if ch == "{":
depth += 1
continue
if ch == "}":
depth -= 1
if depth == 0:
return src[brace_start + 1 : i]
raise AssertionError(f"{locale_key} locale block braces are not balanced")
def test_vietnamese_locale_includes_representative_translations():
src = read(REPO / "static" / "i18n.js")
vi_block = extract_locale_block(src, "vi")
expected = [
"settings_heading_title: 'Trung tâm điều khiển'",
"settings_heading_subtitle: 'Tùy chọn, công cụ hội thoại và điều khiển hệ thống.'",
"approval_skip_all: 'Bỏ qua tất cả trong phiên này'",
"checkpoint_title: 'Checkpoint'",
"composer_send: 'Gửi tin nhắn'",
"gateway_restart: 'Khởi động lại'",
"wiki_browse: 'Duyệt wiki'",
"yolo_pill_title_active: 'Chế độ YOLO đang bật — bấm để tắt'",
]
for entry in expected:
assert entry in vi_block
def test_vietnamese_locale_covers_english_keys():
src = read(REPO / "static" / "i18n.js")
key_pattern = re.compile(r"^\s{4}([a-zA-Z0-9_]+):", re.MULTILINE)
en_keys = set(key_pattern.findall(extract_locale_block(src, "en")))
vi_keys = set(key_pattern.findall(extract_locale_block(src, "vi")))
missing = sorted((en_keys - vi_keys) - PROFILE_CONCEPT_FALLBACK_KEYS)
assert not missing, f"Vietnamese locale missing keys: {missing}"
def test_vietnamese_locale_has_no_duplicate_keys():
src = read(REPO / "static" / "i18n.js")
key_pattern = re.compile(r"^\s{4}([a-zA-Z0-9_]+):", re.MULTILINE)
keys = key_pattern.findall(extract_locale_block(src, "vi"))
duplicates = sorted(k for k, count in Counter(keys).items() if count > 1)
assert not duplicates, f"Vietnamese locale has duplicate keys: {duplicates}"