Files
hermes-webui/api
happy5318 70646b3502 fix(i18n): explicit server tri-state for language + reviewer 4-row table regression (#7730 round 4)
Round-3 removed the `"language": "en"` schema default so fresh installs stopped
reporting a fake explicit English, and dropped the `primary === 'en'` skip.
The maintainer's round-4 gate asked to complete the tri-state shape:

1. `load_settings()` now emits an explicit `None` for the unset case
   (`settings.setdefault("language", None)`) so `/api/settings` carries a
   real three-way signal instead of omitting the key: `null` = no
   preference, "en" = explicitly saved English, any other code = chosen
   locale.  Stored values (including legacy pre-change English picks) still
   win via the merge and are untouched.
2. New `TestReviewerTableServerTriState` regression loads the real
   `static/i18n.js` in a Node `vm` sandbox and drives
   `resolvePreferredLocale(s.language, localStorage.getItem('hermes-lang'),
   _detectBrowserLanguageHint())` — the exact boot.js call shape — for all
   four rows of the maintainer's reproduction table:
   - `en` + new browser (zh-CN) -> en   (was zh under round-2 skip)
   - `en` + stale ja + en-US -> en      (was ja under round-2 skip)
   - `en` + empty + en-US -> en
   - `fr` + empty + zh-CN -> fr

Verification:
- `python3 -c "import api.config"` OK
- 15/15 in test_issue7622_initial_locale_from_browser.py (14 + new table test)
- 8/8 in test_language_precedence.py
- 60/60 settings + 13/13 password-env + login-locale/autosave/sprint26
  collateral tests pass
- ruff_lint --diff origin/master: 0 new violations
2026-09-23 17:03:27 +08:00
..