- De schermen die in v0.5.x zijn toegevoegd (login/setup, Beveiliging,
Netwerken, Updates, containerpaneel, netwerkkeuze bij installeren) gebruikten
harde Nederlandse teksten terwijl de rest van de UI via t() loopt. Op Engels
gaf dat een mengelmoes. 80 nieuwe sleutels toegevoegd aan nl.json en en.json
en alle literals vervangen.
- t() ondersteunt nu plaatshouders: t('port_taken', {port: 8080, suggested:
8081}). Zo blijven zinnen heel in plaats van in losse stukjes geknipt.
- Nieuw instelscherm voor reverse-proxy-SSO onder Instellingen -> Beveiliging:
modus lokaal/proxy/beide, identiteitsheader en de lijst met vertrouwde
proxy-adressen. De backend (PUT /api/auth/mode) bestond al maar was alleen
met curl te bereiken. Bij het omschakelen naar 'proxy' vraagt de UI om
bevestiging, want die modus schakelt de lokale login uit.
- Nieuw tests/test_i18n.py: sleutelpariteit tussen nl en en, geen lege
waarden, gelijke plaatshouders in beide talen, en een controle dat de UI
geen t()-sleutels gebruikt die nergens gedefinieerd zijn. Die laatste vond
meteen een fout in de eerste opzet.
- 157 tests groen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C7oLCRYzY5ixJ5Sv8Y8EFb
81 lines
3.1 KiB
Python
81 lines
3.1 KiB
Python
"""Vertalingen: nl en en moeten dezelfde sleutels hebben, en de UI mag geen
|
|
sleutels gebruiken die nergens gedefinieerd zijn.
|
|
|
|
Zonder deze test loopt de vertaling stilletjes scheef zodra iemand een scherm
|
|
toevoegt — precies wat er bij de auth-, netwerk- en update-schermen gebeurde.
|
|
"""
|
|
import json
|
|
import re
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
WORTEL = Path(__file__).resolve().parent.parent / "server-up"
|
|
VERTALINGEN = WORTEL / "translations"
|
|
TEMPLATE = WORTEL / "templates" / "index.html"
|
|
|
|
|
|
def _laad(code: str) -> dict:
|
|
data = json.loads((VERTALINGEN / f"{code}.json").read_text(encoding="utf-8"))
|
|
return {k: v for k, v in data.items() if not k.startswith("_")}
|
|
|
|
|
|
def test_nl_en_en_hebben_dezelfde_sleutels():
|
|
nl, en = _laad("nl"), _laad("en")
|
|
alleen_nl = sorted(set(nl) - set(en))
|
|
alleen_en = sorted(set(en) - set(nl))
|
|
assert not alleen_nl, f"Ontbreekt in en.json: {alleen_nl}"
|
|
assert not alleen_en, f"Ontbreekt in nl.json: {alleen_en}"
|
|
|
|
|
|
@pytest.mark.parametrize("code", ["nl", "en"])
|
|
def test_geen_lege_vertalingen(code):
|
|
leeg = [k for k, v in _laad(code).items() if not str(v).strip()]
|
|
assert not leeg, f"Lege waarden in {code}.json: {leeg}"
|
|
|
|
|
|
@pytest.mark.parametrize("code", ["nl", "en"])
|
|
def test_meta_is_compleet(code):
|
|
data = json.loads((VERTALINGEN / f"{code}.json").read_text(encoding="utf-8"))
|
|
meta = data.get("_meta", {})
|
|
assert meta.get("code") == code
|
|
assert meta.get("name")
|
|
|
|
|
|
def test_plaatshouders_komen_overeen():
|
|
"""`{user}` in het Nederlands moet ook in het Engels staan, anders valt er
|
|
bij het vertalen een variabele weg."""
|
|
nl, en = _laad("nl"), _laad("en")
|
|
for sleutel, tekst in nl.items():
|
|
vars_nl = set(re.findall(r"\{(\w+)\}", str(tekst)))
|
|
vars_en = set(re.findall(r"\{(\w+)\}", str(en.get(sleutel, ""))))
|
|
assert vars_nl == vars_en, f"{sleutel}: nl={vars_nl} en={vars_en}"
|
|
|
|
|
|
def test_ui_gebruikt_alleen_bestaande_sleutels():
|
|
regels = TEMPLATE.read_text(encoding="utf-8").splitlines()
|
|
# Commentaarregels overslaan: die noemen t('key') als voorbeeld.
|
|
html = "\n".join(r for r in regels if not r.lstrip().startswith(("//", "*", "/*")))
|
|
gebruikt = set(re.findall(r"\bt\('([a-z0-9_]+)'", html))
|
|
bekend = set(_laad("nl"))
|
|
onbekend = sorted(gebruikt - bekend)
|
|
assert not onbekend, f"t() verwijst naar niet-bestaande sleutels: {onbekend}"
|
|
|
|
|
|
def test_nieuwe_schermen_zijn_vertaald():
|
|
"""Steekproef op de schermen die in v0.5.x zijn toegevoegd."""
|
|
nl = _laad("nl")
|
|
for sleutel in ("login", "setup_title", "security", "auth_mode",
|
|
"trusted_proxies", "networks", "own_ip_hint", "channel",
|
|
"update_now", "rollback", "port_taken", "loading"):
|
|
assert sleutel in nl, f"vertaalsleutel ontbreekt: {sleutel}"
|
|
|
|
|
|
def test_i18n_module_leest_beide_talen(env):
|
|
from core import i18n
|
|
i18n.load()
|
|
codes = {t["code"] for t in i18n.available()}
|
|
assert {"nl", "en"} <= codes
|
|
# strings() valt terug op het Engels voor ontbrekende sleutels.
|
|
assert i18n.strings("nl")["login"]
|
|
assert i18n.strings("en")["login"]
|