Update tests/test_utils_duo.py
Run CI Tests / test (push) Has been cancelled

This commit is contained in:
2025-08-29 10:54:44 +02:00
parent 3cdff137bc
commit 18c0d43d2b
+36 -27
View File
@@ -10,36 +10,38 @@ from slic.utils import DotDir
from slic.utils.duo import PickledDict, Secrets
import slic.utils.duo as pg
# Real tests for PickledDict with file manipulation
class TestPickledDictReal:
"""Tests réels de PickledDict avec manipulation de fichiers"""
# Test set() and get() functionality with persistence
def test_set_get(self):
# Crée et initialise un fichier pickle temporaire
# Create and initialize a temporary pickle file
with NamedTemporaryFile(delete=False) as tmp_file:
tmp_path = tmp_file.name
pickle.dump({}, tmp_file) # Initialise avec dict vide
pickle.dump({}, tmp_file) # Initialize with empty dict
try:
pd = PickledDict(tmp_path)
# 1. Test set() et création fichier
# 1. Test set() and file creation
pd.set("test_key", "test_value")
assert os.path.exists(tmp_path)
# 2. Vérification get()
# 2. Verify get()
assert pd.get("test_key") == "test_value"
# 3. Test multi-valeurs
# 3. Test multiple values
pd.set("key2", 42)
pd.set("key3", [1, 2, 3])
# 4. Persistance
# 4. Persistence check
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
# 5. Missing key should raise
with pytest.raises(KeyError):
pd2.get("missing_key")
@@ -47,23 +49,23 @@ class TestPickledDictReal:
if os.path.exists(tmp_path):
os.unlink(tmp_path)
# Test the _load() method
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
pickle.dump({"initial": "data"}, tmp_file) # Initial data
try:
pd = PickledDict(tmp_path)
# 1. Vérifie chargement initial
# 1. Verify initial load
assert pd._load() == {"initial": "data"}
# 2. Mise à jour
# 2. Update
pd.set("new_key", "new_value")
assert pd._load() == {"initial": "data", "new_key": "new_value"}
# 3. Vérification intégrité
# 3. Integrity check
pd2 = PickledDict(tmp_path)
assert pd2._load() == pd._load()
@@ -72,17 +74,17 @@ class TestPickledDictReal:
os.unlink(tmp_path)
# Tests for Secrets with full getpass mocking
class TestSecrets:
"""Tests de Secrets avec mock complet de getpass"""
@pytest.fixture
def setup_env(self, monkeypatch):
"""Fixture qui isole complètement l'environnement"""
# Fixture to isolate environment completely
with TemporaryDirectory() as temp_dir:
temp_path = Path(temp_dir)
monkeypatch.setattr(Path, "home", lambda: temp_path)
# Crée le fichier secrets initial vide
# Create an empty secrets file
secrets_dir = temp_path / ".slic"
secrets_dir.mkdir()
secrets_file = secrets_dir / "secrets"
@@ -91,25 +93,25 @@ class TestSecrets:
yield temp_path
# Full workflow test with mocked getpass
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
# Verify getpass was called
mock_getpass.assert_called_once_with(
prompt='Please enter the secret "test_key": '
)
# Vérifie la persistance
# Verify persistence
secrets2 = Secrets()
assert secrets2.get("test_key") == "test_secret"
# Test multiple secrets storage
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"]
@@ -120,19 +122,21 @@ class TestSecrets:
assert secrets.get("key1") == "secret1"
assert secrets.get("key2") == "secret2"
# Test cancellation by Ctrl+C (KeyboardInterrupt)
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
secrets.set("canceled_key") # Should not crash
# Vérifie que le fichier n'a pas été modifié
# Verify file remains unchanged
secrets_file = setup_env / ".slic" / "secrets"
with open(secrets_file, "rb") as f:
assert pickle.load(f) == {}
# Dummy response object for mocking requests
class DummyResponse:
def __init__(self, data):
self._data = data
@@ -140,14 +144,15 @@ class DummyResponse:
return self._data
# Test that get_pgroup raises if KEY is missing
def test_get_pgroup_raises_if_no_key(monkeypatch):
monkeypatch.setattr(pg, "KEY", None)
with pytest.raises(ValueError, match="no secret for duo known"):
pg.get_pgroup("p99999")
# Test case where firstname/lastname == pi_firstname/pi_lastname
def test_get_pgroup_info_with_props_same_name_and_pi(monkeypatch):
"""Cas props : firstname/lastname == pi_firstname/pi_lastname"""
monkeypatch.setattr(pg, "KEY", "secret123")
dummy_data = {
@@ -173,8 +178,8 @@ def test_get_pgroup_info_with_props_same_name_and_pi(monkeypatch):
assert res["title"] == "CoolTitle (P1)"
# Test case where firstname/lastname != pi_firstname/pi_lastname
def test_get_pgroup_info_with_props_different_pi(monkeypatch):
"""Cas props : firstname/lastname ≠ pi_firstname/pi_lastname"""
monkeypatch.setattr(pg, "KEY", "secret123")
dummy_data = {
@@ -200,6 +205,7 @@ def test_get_pgroup_info_with_props_different_pi(monkeypatch):
assert res["title"] == "CoolTitle (P2)"
# Test case without proposals but with owner info
def test_get_pgroup_info_without_props_with_owner(monkeypatch):
monkeypatch.setattr(pg, "KEY", "secret123")
@@ -220,6 +226,7 @@ def test_get_pgroup_info_without_props_with_owner(monkeypatch):
assert res["title"] == "SomeComment"
# Test case without proposals and no owner info
def test_get_pgroup_info_without_props_no_owner(monkeypatch):
monkeypatch.setattr(pg, "KEY", "secret123")
@@ -238,8 +245,10 @@ def test_get_pgroup_info_without_props_no_owner(monkeypatch):
assert res["name"] == "unknown"
assert res["title"] == "Fallback"
# Test get_pgroup_info using a mocked get_pgroup
def test_get_pgroup_info_mock(monkeypatch):
# Mock pour bypass Secrets().get()
# Mock to bypass Secrets().get()
monkeypatch.setattr(pg, "KEY", "fake-key")
def fake_get(p):
@@ -253,4 +262,4 @@ def test_get_pgroup_info_mock(monkeypatch):
assert set(res.keys()) == {"name", "title", "type"}
for key in ("name", "title", "type"):
assert isinstance(res[key], str)
assert res[key]
assert res[key]