From 18c0d43d2bc14afc30848b76cb8d871da28eb523 Mon Sep 17 00:00:00 2001 From: tligui_y Date: Fri, 29 Aug 2025 10:54:44 +0200 Subject: [PATCH] Update tests/test_utils_duo.py --- tests/test_utils_duo.py | 63 +++++++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 27 deletions(-) diff --git a/tests/test_utils_duo.py b/tests/test_utils_duo.py index e4b3139b9..e33c36f67 100644 --- a/tests/test_utils_duo.py +++ b/tests/test_utils_duo.py @@ -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] \ No newline at end of file + assert res[key]