104 lines
4.1 KiB
Python
104 lines
4.1 KiB
Python
|
|
#!/usr/bin/env python3
|
||
|
|
# © 2026 TechnoLibre (http://www.technolibre.ca)
|
||
|
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
|
||
|
|
|
||
|
|
"""La langue du binaire du cache, vue du menu.
|
||
|
|
|
||
|
|
Le binaire traduit ses messages humains selon --lang. Le menu doit donc dire
|
||
|
|
laquelle il veut, et la bonne : la langue de todo.py pour ce qu'il AFFICHE,
|
||
|
|
le français pour ce qu'il LIT — il ne connaît les libellés que dans cette
|
||
|
|
langue. Et ce qu'il lit dans un journal écrit par le service, dont la langue
|
||
|
|
est fixée à l'installation, il doit le reconnaître dans les deux.
|
||
|
|
"""
|
||
|
|
|
||
|
|
import sys
|
||
|
|
import unittest
|
||
|
|
from pathlib import Path
|
||
|
|
from unittest import mock
|
||
|
|
|
||
|
|
RACINE = Path(__file__).resolve().parent.parent
|
||
|
|
sys.path.insert(0, str(RACINE))
|
||
|
|
|
||
|
|
from script.todo import qemu_cache_menu as menu # noqa: E402
|
||
|
|
|
||
|
|
CATALOGUE = RACINE / "script" / "qemu_cache" / "catalogue_en.go"
|
||
|
|
|
||
|
|
|
||
|
|
class TestLOptionDeLangue(unittest.TestCase):
|
||
|
|
def test_une_sortie_lue_est_demandee_en_francais(self):
|
||
|
|
with mock.patch.object(menu, "get_lang", return_value="en"):
|
||
|
|
self.assertEqual(menu.option_langue(lue=True), "--lang fr")
|
||
|
|
|
||
|
|
def test_une_sortie_affichee_suit_la_langue_de_todo(self):
|
||
|
|
for langue in ("fr", "en"):
|
||
|
|
with mock.patch.object(menu, "get_lang", return_value=langue):
|
||
|
|
self.assertEqual(menu.option_langue(), f"--lang {langue}")
|
||
|
|
|
||
|
|
def test_le_pre_remplissage_parle_la_langue_de_todo(self):
|
||
|
|
"""Lancé par sudo -u : EL_LANG n'y arriverait pas, l'option si."""
|
||
|
|
with mock.patch.object(menu, "get_lang", return_value="en"):
|
||
|
|
cmd = menu.miroir_prefetch_cmd("/tmp/liste", [])
|
||
|
|
self.assertIn("--lang en", cmd)
|
||
|
|
|
||
|
|
def test_le_retrait_d_exception_garde_nft_en_bout_de_tube(self):
|
||
|
|
"""Le message humain va à l'erreur standard ; la sortie standard
|
||
|
|
porte les règles que nft lit, et ne se traduit jamais."""
|
||
|
|
with mock.patch.object(menu, "get_lang", return_value="en"):
|
||
|
|
cmd = menu.bypass_retrait_cmd("52:54:00:00:00:04")
|
||
|
|
self.assertIn("--lang en", cmd)
|
||
|
|
self.assertTrue(cmd.endswith("| sudo nft -f -"))
|
||
|
|
|
||
|
|
|
||
|
|
class TestCeQueLeMenuLit(unittest.TestCase):
|
||
|
|
def test_l_occupation_du_miroir_est_lue_en_francais(self):
|
||
|
|
vu = {}
|
||
|
|
|
||
|
|
def faux_lire(cmd, delai=15):
|
||
|
|
vu["cmd"] = cmd
|
||
|
|
return "objets : 3\ndépôts git : 12 en miroir, 4.2 Gio\n"
|
||
|
|
|
||
|
|
with mock.patch.object(
|
||
|
|
menu.QemuCacheMenuMixin, "_cache_lire", staticmethod(faux_lire)
|
||
|
|
), mock.patch.object(menu, "get_lang", return_value="en"):
|
||
|
|
rendu = menu.QemuCacheMenuMixin._cache_miroir_occupation()
|
||
|
|
self.assertIn("--lang fr", vu["cmd"])
|
||
|
|
self.assertEqual(rendu, ("12", "4.2 Gio"))
|
||
|
|
|
||
|
|
def test_le_journal_est_lu_dans_les_deux_langues(self):
|
||
|
|
"""La langue du service est celle de son installation, pas celle de
|
||
|
|
qui ouvre le menu : un refus appris doit être reconnu dans les deux."""
|
||
|
|
journal = (
|
||
|
|
"tunnel opaque retenu pour npm.example (3 échec(s)) : EOF\n"
|
||
|
|
"opaque tunnel kept for pypi.example (3 failure(s)): EOF\n"
|
||
|
|
)
|
||
|
|
commandes = []
|
||
|
|
|
||
|
|
def faux_lire(cmd, delai=15):
|
||
|
|
commandes.append(cmd)
|
||
|
|
return journal
|
||
|
|
|
||
|
|
with mock.patch.object(
|
||
|
|
menu.QemuCacheMenuMixin, "_cache_lire", staticmethod(faux_lire)
|
||
|
|
):
|
||
|
|
hotes = menu.QemuCacheMenuMixin._cache_refus_appris()
|
||
|
|
self.assertEqual(hotes, ["npm.example", "pypi.example"])
|
||
|
|
for motif in menu.REFUS_APPRIS:
|
||
|
|
self.assertIn(motif, commandes[0])
|
||
|
|
|
||
|
|
def test_le_catalogue_porte_ce_que_le_menu_lit(self):
|
||
|
|
"""Une traduction qui s'écarte de ces libellés rendrait le menu
|
||
|
|
aveugle sans qu'aucun test du binaire ne le voie."""
|
||
|
|
texte = CATALOGUE.read_text(encoding="utf-8")
|
||
|
|
self.assertIn('"opaque tunnel kept for %s (', texte)
|
||
|
|
for libelle in ("authority : %s", "fingerprint : %s"):
|
||
|
|
self.assertIn(f'"{libelle}', texte)
|
||
|
|
for prefixe in menu.LIBELLES_TUS:
|
||
|
|
self.assertTrue(
|
||
|
|
prefixe in texte or prefixe in ("autorité", "empreinte"),
|
||
|
|
prefixe,
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
if __name__ == "__main__":
|
||
|
|
unittest.main()
|