securite: #87 T6-T8 fin dette — deps qualifiées, semgrep, Secure auto, CORS
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
"""Parité i18n FR/EN des locales du frontend (#87 T9).
|
||||
|
||||
`frontend/locales/fr.json` et `en.json` doivent exposer exactement les mêmes
|
||||
clés (comparaison profonde) : toute clé manquante fait afficher la clé brute
|
||||
dans l'UI au lieu du libellé.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
LOCALES = Path(__file__).resolve().parent.parent / "frontend" / "locales"
|
||||
|
||||
|
||||
def _flat(d: dict, prefix: str = "") -> set[str]:
|
||||
keys = set()
|
||||
for k, v in d.items():
|
||||
name = f"{prefix}.{k}" if prefix else str(k)
|
||||
if isinstance(v, dict):
|
||||
keys |= _flat(v, name)
|
||||
else:
|
||||
keys.add(name)
|
||||
return keys
|
||||
|
||||
|
||||
def _load(lang: str) -> set[str]:
|
||||
return _flat(json.loads((LOCALES / f"{lang}.json").read_text(encoding="utf-8")))
|
||||
|
||||
|
||||
class TestI18nParity:
|
||||
def test_fr_en_same_keys(self):
|
||||
fr, en = _load("fr"), _load("en")
|
||||
assert not (fr - en), f"clés sans traduction EN : {sorted(fr - en)[:10]}"
|
||||
assert not (en - fr), f"clés sans traduction FR : {sorted(en - fr)[:10]}"
|
||||
Reference in New Issue
Block a user