154 lines
5.2 KiB
Python
154 lines
5.2 KiB
Python
import os
|
||
import pickle
|
||
import pytest
|
||
import requests
|
||
from tempfile import NamedTemporaryFile, TemporaryDirectory
|
||
from unittest.mock import patch, MagicMock
|
||
from getpass import getpass
|
||
from pathlib import Path
|
||
from slic.utils import DotDir
|
||
from slic.utils.duo import PickledDict, Secrets
|
||
|
||
URL = "https://duo.psi.ch/duo/api.php/v1/CalendarInfos/pgroup/"
|
||
|
||
class TestPickledDictReal:
|
||
"""Tests réels de PickledDict avec manipulation de fichiers"""
|
||
|
||
def test_set_get(self):
|
||
# Crée et initialise un fichier pickle temporaire
|
||
with NamedTemporaryFile(delete=False) as tmp_file:
|
||
tmp_path = tmp_file.name
|
||
pickle.dump({}, tmp_file) # Initialise avec dict vide
|
||
|
||
try:
|
||
pd = PickledDict(tmp_path)
|
||
|
||
# 1. Test set() et création fichier
|
||
pd.set("test_key", "test_value")
|
||
assert os.path.exists(tmp_path)
|
||
|
||
# 2. Vérification get()
|
||
assert pd.get("test_key") == "test_value"
|
||
|
||
# 3. Test multi-valeurs
|
||
pd.set("key2", 42)
|
||
pd.set("key3", [1, 2, 3])
|
||
|
||
# 4. Persistance
|
||
pd2 = PickledDict(tmp_path)
|
||
assert pd2.get("test_key") == "test_value"
|
||
assert pd2.get("key2") == 42
|
||
assert pd2.get("key3") == [1, 2, 3]
|
||
|
||
# 5. Test clé manquante
|
||
with pytest.raises(KeyError):
|
||
pd2.get("missing_key")
|
||
|
||
finally:
|
||
if os.path.exists(tmp_path):
|
||
os.unlink(tmp_path)
|
||
|
||
def test_load(self):
|
||
"""Test de la méthode _load()"""
|
||
with NamedTemporaryFile(delete=False) as tmp_file:
|
||
tmp_path = tmp_file.name
|
||
pickle.dump({"initial": "data"}, tmp_file) # Données initiales
|
||
|
||
try:
|
||
pd = PickledDict(tmp_path)
|
||
|
||
# 1. Vérifie chargement initial
|
||
assert pd._load() == {"initial": "data"}
|
||
|
||
# 2. Mise à jour
|
||
pd.set("new_key", "new_value")
|
||
assert pd._load() == {"initial": "data", "new_key": "new_value"}
|
||
|
||
# 3. Vérification intégrité
|
||
pd2 = PickledDict(tmp_path)
|
||
assert pd2._load() == pd._load()
|
||
|
||
finally:
|
||
if os.path.exists(tmp_path):
|
||
os.unlink(tmp_path)
|
||
|
||
|
||
class TestSecrets:
|
||
"""Tests de Secrets avec mock complet de getpass"""
|
||
|
||
@pytest.fixture
|
||
def setup_env(self, monkeypatch):
|
||
"""Fixture qui isole complètement l'environnement"""
|
||
with TemporaryDirectory() as temp_dir:
|
||
temp_path = Path(temp_dir)
|
||
monkeypatch.setattr(Path, "home", lambda: temp_path)
|
||
|
||
# Crée le fichier secrets initial vide
|
||
secrets_dir = temp_path / ".slic"
|
||
secrets_dir.mkdir()
|
||
secrets_file = secrets_dir / "secrets"
|
||
with open(secrets_file, "wb") as f:
|
||
pickle.dump({}, f)
|
||
|
||
yield temp_path
|
||
|
||
def test_secret_workflow(self, setup_env):
|
||
"""Test complet avec mock de getpass"""
|
||
with patch('slic.utils.duo.getpass') as mock_getpass:
|
||
mock_getpass.return_value = "test_secret"
|
||
|
||
secrets = Secrets()
|
||
secrets.set("test_key")
|
||
|
||
# Vérifie que getpass a été appelé correctement
|
||
mock_getpass.assert_called_once_with(
|
||
prompt='Please enter the secret "test_key": '
|
||
)
|
||
|
||
# Vérifie la persistance
|
||
secrets2 = Secrets()
|
||
assert secrets2.get("test_key") == "test_secret"
|
||
|
||
def test_multiple_secrets(self, setup_env):
|
||
"""Test avec plusieurs secrets"""
|
||
with patch('slic.utils.duo.getpass') as mock_getpass:
|
||
mock_getpass.side_effect = ["secret1", "secret2"]
|
||
|
||
secrets = Secrets()
|
||
secrets.set("key1")
|
||
secrets.set("key2")
|
||
|
||
assert secrets.get("key1") == "secret1"
|
||
assert secrets.get("key2") == "secret2"
|
||
|
||
def test_keyboard_interrupt(self, setup_env):
|
||
"""Test de l'annulation par Ctrl+C"""
|
||
with patch('slic.utils.duo.getpass') as mock_getpass:
|
||
mock_getpass.side_effect = KeyboardInterrupt()
|
||
|
||
secrets = Secrets()
|
||
secrets.set("canceled_key") # Ne devrait pas crasher
|
||
|
||
# Vérifie que le fichier n'a pas été modifié
|
||
secrets_file = setup_env / ".slic" / "secrets"
|
||
with open(secrets_file, "rb") as f:
|
||
assert pickle.load(f) == {}
|
||
|
||
def test_list_pgroups():
|
||
"""Return the list of available pgroups (IDs and names)."""
|
||
KEY = "fried-BRAN-gorgon-togo-fledge-mummify-dustbin-advert"
|
||
headers = {"x-api-secret": KEY}
|
||
|
||
resp = requests.get(URL, headers=headers)
|
||
resp.raise_for_status()
|
||
|
||
data = resp.json()
|
||
|
||
# Les structures d’API peuvent varier, tu adaptes selon la vraie réponse
|
||
groups = []
|
||
for g in data:
|
||
group_id = g.get("id") or g.get("pgroup") or "unknown"
|
||
name = g.get("name") or g.get("comments") or "unnamed"
|
||
groups.append((group_id, name))
|
||
print("GRRRRRRRRP : ", groups)
|
||
return groups |