tests/test_actions.py
Rama main · réplica de lectura del repositorio original.
"""Tests du module d'actions : détection, confirmation OUI, expiration."""
import asyncio
from app import actions
async def test_detect_action_redemarrage_jellyfin():
label, action = actions.detect_action("redémarre jellyfin stp")
assert action == "docker_restart_102_jellyfin"
async def test_detect_action_hors_whitelist():
assert actions.detect_action("éteins le serveur") is None
assert actions.detect_action("supprime tout") is None
async def test_lxc_restart_capture_le_numero():
_, action = actions.detect_action("redémarre le CT 102")
assert action == "lxc_restart_102"
async def test_detect_updates_scan():
for phrase in (
"check les updates",
"vérifie les mises à jour",
"cherche les nouvelles images",
"/checkupdates",
):
label, action = actions.detect_action(phrase)
assert action == "docker_updates_scan", phrase
async def test_detect_updates_apply():
for phrase in ("applique les mises à jour", "mets à jour les conteneurs", "/maj"):
label, action = actions.detect_action(phrase)
assert action == "docker_updates_apply", phrase
async def test_updates_scan_ne_declenche_pas_apply():
# Le mot « updates » seul (scan) ne doit pas matcher le pattern apply
label, action = actions.detect_action("check updates")
assert action == "docker_updates_scan"
async def test_confirmation_sans_action_en_attente():
actions._PENDING.clear()
reply = await actions.confirm_pending("OUI", "test:user")
assert "Aucune action en attente" in reply
async def test_flux_complet_propose_puis_confirme(monkeypatch):
actions._PENDING.clear()
executed = []
async def fake_execute(action):
executed.append(action)
return "OK action simulée"
monkeypatch.setattr(actions, "_execute", fake_execute)
propose_reply = actions.propose("docker_restart_102_jellyfin", "test:user")
assert "OUI" in propose_reply
assert executed == []
confirm_reply = await actions.confirm_pending("OUI", "test:user")
assert executed == ["docker_restart_102_jellyfin"]
assert "OK action simulée" in confirm_reply
async def test_confirmation_expire_apres_ttl(monkeypatch):
actions._PENDING.clear()
async def fail_execute(action):
raise AssertionError("l'action expirée ne doit pas s'exécuter")
monkeypatch.setattr(actions, "_execute", fail_execute)
actions.propose("docker_restart_102_jellyfin", "test:user")
# Vieillir la proposition au-delà du TTL
action, _ = actions._PENDING["test:user"]
actions._PENDING["test:user"] = (action, actions.time.monotonic() - actions.PENDING_TTL_S - 1)
reply = await actions.confirm_pending("OUI", "test:user")
assert "Aucune action en attente" in reply
assert "test:user" not in actions._PENDING
async def test_texte_qui_n_est_pas_une_confirmation_ne_consomme_pas():
actions._PENDING.clear()
actions.propose("docker_restart_102_jellyfin", "test:user")
assert await actions.confirm_pending("oui mais non", "test:user") is None
assert "test:user" in actions._PENDING
actions._PENDING.clear()