Repository navigation
fix: validateLanguage keeps the player's language instead of always en_GB (#937) - #1014
ismisepaul wants to merge 3 commits into
Conversation
…n_GB (#937) validateLanguage only accepted a session lang matching ".[a-z]{2}-[A-Z]{2}$", but the language picker stores two-letter codes (es, fr, ...) and translation.jsp stores the request Locale (es_ES), so it always returned en_GB and every lesson and challenge answered in English whatever language was picked. Accept a two-letter language, optionally with a region, and return the language when it is one the picker offers. Anything else still falls back to en_GB. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
🟢 Approval recommended
The focused implementation matches the intended language handling and includes appropriate regression coverage, with no unresolved findings.
No open issues 🎉
What changed in this PR
Fixes #937 so lesson and challenge responses use the player’s supported language instead of always falling back to English.
Changes:
- Accepts picker language codes and normalizes region-qualified values to supported two-letter codes.
- Preserves the
en_GBfallback for missing, unsupported, or malformed values. - Adds regression tests in a separate class to avoid overlap with #954.
| File | Description |
|---|---|
| src/test/java/utils/ValidateLanguageTest.java | Tests supported codes, locale normalization, and fallback behavior. |
| src/main/java/utils/Validate.java | Validates and normalizes session languages against the picker’s supported options. |
Review effort: Balanced
SeanDuggan
left a comment
There was a problem hiding this comment.
I merged this with current dev, and spotless and the full unit suite pass. I also did the manual language check on a running instance, in open-floor mode where RefreshMenu actually calls validateLanguage. English, Español and Français switch correctly. pt works too, and so do es_ES and pt-BR, which reduce to es and pt. Unsupported or malformed values (de, xen-GB) fall back to English. I switched languages with the picker only for English, Español and Français and used ?lang= for the rest.
One thing outside this PR that you may want to follow up on: in incremental-floor mode RefreshMenu and index.jsp pass the raw session lang to Getter.getIncrementalModules, so a regional value like es_ES shows English in that mode.
There was a problem hiding this comment.
🟡 Changes recommended
The manual acceptance steps require Spanish and French SQL Injection responses despite the lesson having only an English bundle, causing false failures and needing correction to use an existing translation.
Review effort: Balanced
| if (lang.matches("^[a-z]{2}([_-][A-Za-z]{2})?$")) { | ||
| String language = lang.substring(0, 2); | ||
| if (SUPPORTED_LANGUAGES.contains(language)) { | ||
| result = language; |

The unit test proves the language code is now kept. Whether lessons then really answer in that language depends on each level's translation files, which only a running app shows.
Please run this branch, follow the steps, and comment on this PR with the result: pass, or the step that failed and what you saw.
Branch:
dev#937-validate-languageSet up. Use a machine where the Shepherd Docker volumes can be thrown away:
down -vdeletes their data. JDK 17 and Maven 3.9.2+ are needed.git fetch origin git checkout 'dev#937-validate-language' mvn -Pdocker clean install -DskipTests docker compose down -v docker compose up -d --buildadmin/passwordand set a new password when asked.Test
test. The reply should be in Spanish.It's broken if: replies stay in English after you pick Spanish or French, or a page shows an error after you switch language.
Fixes #937.
What
Validate.validateLanguageaccepted a sessionlangonly if it matched.[a-z]{2}-[A-Z]{2}$. Nothing stores that format: the picker (translation-select.jsp) stores two-letter codes (es,fr, …), andtranslation.jspstores the requestLocale(es_ES). So it always returneden_GB, and every lesson and challenge answered in English, whatever language the player picked.It now accepts a two-letter language, optionally followed by a region (
es,es_ES,pt-BR), and returns the language when it is one the picker offers: en, es, fr, pt, ga, zh, hi, ru. Anything else, including a missing session or attribute, still falls back toen_GB.Tests
ValidateLanguageTest(unit):es_ES,pt-BRand aLocaleobject are reduced to the language;en_GB:de,xen-GB,EN,english,../es,es_ES_xand the empty string;en_GB.It fails 3 of 4 on
dev, for exampleexpected: <es> but was: <en_GB>.It's a new class rather than additions to
ValidateTest, so it doesn't conflict with #954, which edits that file. Every step oftest.ymlpassed locally (lint, build, PGP check, compose build, Tomcat config check, unit tests, integration tests).🤖 Generated with Claude Code