diff --git a/backend/chainlit/translations/ar-SA.json b/backend/chainlit/translations/ar-SA.json index b98b427d23..b5de794c3d 100644 --- a/backend/chainlit/translations/ar-SA.json +++ b/backend/chainlit/translations/ar-SA.json @@ -68,6 +68,7 @@ "favorites": { "use": "استخدام رسالة مفضلة", "headline": "الرسائل المفضلة", + "remove": "إزالة من المفضلة", "empty": { "title": "لا توجد رسائل محفوظة بعد", "description": "ابدأ بإرسال رسالة وقم بتمييزها بنجمة أو ميّز رسالة من محادثاتك السابقة" diff --git a/backend/chainlit/translations/da-DK.json b/backend/chainlit/translations/da-DK.json index aba214e617..8c9e8607b0 100644 --- a/backend/chainlit/translations/da-DK.json +++ b/backend/chainlit/translations/da-DK.json @@ -68,6 +68,7 @@ "favorites": { "use": "Brug en favorit besked", "headline": "Favorit beskeder", + "remove": "Fjern favorit", "empty": { "title": "Ingen gemte prompts endnu", "description": "Start med at sende en prompt og markere den med en stjerne, eller vælg en prompt fra tidligere samtaler" diff --git a/backend/chainlit/translations/de-DE.json b/backend/chainlit/translations/de-DE.json index db5934b6f1..1469a3f569 100644 --- a/backend/chainlit/translations/de-DE.json +++ b/backend/chainlit/translations/de-DE.json @@ -249,6 +249,12 @@ "components": { "MultiSelectInput": { "placeholder": "Wähle aus..." + }, + "DatePickerInput": { + "placeholder": { + "single": "Datum auswählen", + "range": "Datumsbereich auswählen" + } } } } diff --git a/backend/chainlit/translations/it.json b/backend/chainlit/translations/it.json index 69021fe630..bad83ea185 100644 --- a/backend/chainlit/translations/it.json +++ b/backend/chainlit/translations/it.json @@ -249,6 +249,12 @@ "components": { "MultiSelectInput": { "placeholder": "Seleziona..." + }, + "DatePickerInput": { + "placeholder": { + "single": "Seleziona una data", + "range": "Seleziona un intervallo di date" + } } } } diff --git a/backend/chainlit/translations/ja.json b/backend/chainlit/translations/ja.json index b1ea49659b..2762908e41 100644 --- a/backend/chainlit/translations/ja.json +++ b/backend/chainlit/translations/ja.json @@ -86,6 +86,7 @@ }, "fileUpload": { "dragDrop": "ここにファイルをドラッグ&ドロップ", + "browse": "ファイルを選択", "sizeLimit": "制限:", "errors": { "failed": "アップロードに失敗しました", diff --git a/backend/chainlit/translations/ko.json b/backend/chainlit/translations/ko.json index f05622faf1..3a0cca3bf2 100644 --- a/backend/chainlit/translations/ko.json +++ b/backend/chainlit/translations/ko.json @@ -249,6 +249,12 @@ "components": { "MultiSelectInput": { "placeholder": "선택..." + }, + "DatePickerInput": { + "placeholder": { + "single": "날짜 선택", + "range": "날짜 범위 선택" + } } } } diff --git a/backend/tests/test_translations.py b/backend/tests/test_translations.py index 6e517c4748..6b852b87d8 100644 --- a/backend/tests/test_translations.py +++ b/backend/tests/test_translations.py @@ -1,8 +1,11 @@ +import json +import os from io import StringIO from unittest.mock import patch import pytest +from chainlit.config import TRANSLATIONS_DIR from chainlit.translations import compare_json_structures, lint_translation_json @@ -384,3 +387,40 @@ def test_compare_preserves_error_order(self): missing_errors = [e for e in errors if "Missing" in e] assert len(extra_errors) == 2 assert len(missing_errors) == 3 + + +def _load_translation(filename): + with open(os.path.join(TRANSLATIONS_DIR, filename), encoding="utf-8") as f: + return json.load(f) + + +_TRUTH_LOCALE = "en-US.json" +_LOCALE_FILES = sorted(f for f in os.listdir(TRANSLATIONS_DIR) if f.endswith(".json")) + + +class TestTranslationFileParity: + """Every shipped locale file must carry every key in en-US.json. + + This walks the real backend/chainlit/translations/ directory rather than + synthetic dictionaries, so a PR that adds a key to en-US.json without + updating the other locales fails here instead of shipping silently. + """ + + @pytest.mark.parametrize("locale_file", _LOCALE_FILES) + def test_locale_has_no_missing_or_mismatched_keys(self, locale_file): + truth = _load_translation(_TRUTH_LOCALE) + # Comparing en-US.json to itself is expected to be trivially clean — + # it is both a locale file and the ground truth. + to_compare = _load_translation(locale_file) + + errors = compare_json_structures(truth, to_compare) + # "Extra key" is excluded: a locale carrying a key en-US.json doesn't + # (yet) have is not a rendering regression. Missing keys and structure + # mismatches both are — a key present as the wrong shape (e.g. an + # object where en-US.json has a string) breaks rendering exactly like + # a missing key does, so both must fail here. + relevant = [e for e in errors if "Extra" not in e] + + assert relevant == [], ( + f"{locale_file} diverges from {_TRUTH_LOCALE}: {relevant}" + )