This commit is contained in:
+65
-90
@@ -1,80 +1,69 @@
|
||||
import os
|
||||
import pickle
|
||||
import pytest
|
||||
from tempfile import NamedTemporaryFile
|
||||
from tempfile import NamedTemporaryFile, TemporaryDirectory
|
||||
from unittest.mock import patch
|
||||
from getpass import getpass
|
||||
from pathlib import Path
|
||||
from slic.utils.duo import *
|
||||
from slic.utils import DotDir
|
||||
from slic.utils.duo import PickledDict, Secrets
|
||||
|
||||
class TestPickledDictReal:
|
||||
"""Tests réels de PickledDict avec manipulation de fichiers"""
|
||||
|
||||
def test_set_get(self):
|
||||
# Crée un fichier temporaire qui sera automatiquement supprimé
|
||||
# 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:
|
||||
# 1. Test avec fichier vide au départ
|
||||
pd = PickledDict(tmp_path)
|
||||
|
||||
# 2. Premier set() - doit créer le fichier
|
||||
# 1. Test set() et création fichier
|
||||
pd.set("test_key", "test_value")
|
||||
assert os.path.exists(tmp_path) # Le fichier doit exister
|
||||
assert os.path.exists(tmp_path)
|
||||
|
||||
# 3. Vérifie que les données sont bien persistées
|
||||
pd2 = PickledDict(tmp_path)
|
||||
assert pd2.get("test_key") == "test_value"
|
||||
# 2. Vérification get()
|
||||
assert pd.get("test_key") == "test_value"
|
||||
|
||||
# 4. Test avec plusieurs valeurs
|
||||
# 3. Test multi-valeurs
|
||||
pd.set("key2", 42)
|
||||
pd.set("key3", [1, 2, 3])
|
||||
|
||||
# 5. Vérifie l'intégrité des données
|
||||
pd3 = PickledDict(tmp_path)
|
||||
assert pd3.get("test_key") == "test_value"
|
||||
assert pd3.get("key2") == 42
|
||||
assert pd3.get("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]
|
||||
|
||||
# 6. Test KeyError
|
||||
# 5. Test clé manquante
|
||||
with pytest.raises(KeyError):
|
||||
pd3.get("non_existent_key")
|
||||
pd2.get("missing_key")
|
||||
|
||||
finally:
|
||||
# Nettoyage
|
||||
if os.path.exists(tmp_path):
|
||||
os.unlink(tmp_path)
|
||||
|
||||
|
||||
def test_load(self):
|
||||
"""Test complet du workflow avec vérification de _load()"""
|
||||
"""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)
|
||||
|
||||
# Vérifie que _load() retourne bien un dict vide au début
|
||||
assert pd._load() == {}
|
||||
# 1. Vérifie chargement initial
|
||||
assert pd._load() == {"initial": "data"}
|
||||
|
||||
# Premier set
|
||||
pd.set("test_key", "test_value")
|
||||
# 2. Mise à jour
|
||||
pd.set("new_key", "new_value")
|
||||
assert pd._load() == {"initial": "data", "new_key": "new_value"}
|
||||
|
||||
# Vérifie le contenu via _load()
|
||||
assert pd._load() == {"test_key": "test_value"}
|
||||
|
||||
# Ajout de données complexes
|
||||
pd.set("key2", {"nested": True})
|
||||
|
||||
# Vérification via _load()
|
||||
loaded_data = pd._load()
|
||||
assert loaded_data["test_key"] == "test_value"
|
||||
assert loaded_data["key2"] == {"nested": True}
|
||||
|
||||
# Test avec une nouvelle instance
|
||||
# 3. Vérification intégrité
|
||||
pd2 = PickledDict(tmp_path)
|
||||
assert pd2._load() == loaded_data # Doit être identique
|
||||
assert pd2._load() == pd._load()
|
||||
|
||||
finally:
|
||||
if os.path.exists(tmp_path):
|
||||
@@ -82,72 +71,58 @@ class TestPickledDictReal:
|
||||
|
||||
|
||||
class TestSecrets:
|
||||
"""Tests réels de Secrets avec le nom de fichier par défaut"""
|
||||
"""Tests réels de Secrets avec isolation du home directory"""
|
||||
|
||||
@pytest.fixture
|
||||
def secrets_dir(self, tmp_path):
|
||||
"""Crée un répertoire temporaire avec une structure .dir"""
|
||||
dot_dir = tmp_path / ".dir"
|
||||
dot_dir.mkdir()
|
||||
return dot_dir
|
||||
def temp_home(self, monkeypatch):
|
||||
"""Crée un home temporaire et mock Path.home()"""
|
||||
with TemporaryDirectory() as temp_dir:
|
||||
temp_path = Path(temp_dir)
|
||||
monkeypatch.setattr(Path, "home", lambda: temp_path)
|
||||
yield temp_path
|
||||
|
||||
def test_default_filename(self, secrets_dir, monkeypatch):
|
||||
"""Test que le fichier par défaut 'secrets' est bien utilisé"""
|
||||
# 1. On mock DotDir pour utiliser notre répertoire temporaire
|
||||
monkeypatch.setattr("mon_module.DotDir", lambda: lambda _: str(secrets_dir / "secrets"))
|
||||
|
||||
# 2. Test avec le nom par défaut
|
||||
secrets = Secrets() # Utilise fname="secrets" par défaut
|
||||
|
||||
with patch("getpass.getpass", return_value="default_secret"):
|
||||
secrets.set("default_key")
|
||||
|
||||
# 3. Vérifie que le fichier a bien été créé avec le bon nom
|
||||
expected_file = secrets_dir / "secrets"
|
||||
assert expected_file.exists()
|
||||
|
||||
# 4. Vérifie la persistance
|
||||
secrets2 = Secrets()
|
||||
assert secrets2.get("default_key") == "default_secret"
|
||||
|
||||
def test_secret_workflow(self, secrets_dir, monkeypatch):
|
||||
"""Test complet du workflow avec le nom par défaut"""
|
||||
monkeypatch.setattr("mon_module.DotDir", lambda: lambda _: str(secrets_dir / "secrets"))
|
||||
|
||||
# 1. Premier secret
|
||||
def test_default_filename(self, temp_home):
|
||||
"""Test le stockage dans ~/.slic/secrets"""
|
||||
secrets = Secrets()
|
||||
with patch("getpass.getpass", return_value="first_value"):
|
||||
secrets.set("first_key")
|
||||
|
||||
# 2. Deuxième secret
|
||||
with patch("getpass.getpass", return_value="second_value"):
|
||||
secrets.set("second_key")
|
||||
with patch("getpass.getpass", return_value="secret123"):
|
||||
secrets.set("api_key")
|
||||
|
||||
# 3. Vérification
|
||||
# Vérifie le fichier
|
||||
secret_file = temp_home / ".slic" / "secrets"
|
||||
assert secret_file.exists()
|
||||
|
||||
# Vérifie la persistance
|
||||
secrets2 = Secrets()
|
||||
assert secrets2.get("first_key") == "first_value"
|
||||
assert secrets2.get("second_key") == "second_value"
|
||||
assert secrets2.get("api_key") == "secret123"
|
||||
|
||||
def test_secret_workflow(self, temp_home):
|
||||
"""Test complet du workflow Secrets"""
|
||||
secrets = Secrets()
|
||||
|
||||
# 4. Vérifie le contenu du fichier
|
||||
with open(secrets_dir / "secrets", "rb") as f:
|
||||
# Ajout de deux secrets
|
||||
with patch("getpass.getpass", side_effect=["pass1", "pass2"]):
|
||||
secrets.set("db_user")
|
||||
secrets.set("db_pass")
|
||||
|
||||
# Vérification
|
||||
secrets2 = Secrets()
|
||||
assert secrets2.get("db_user") == "pass1"
|
||||
assert secrets2.get("db_pass") == "pass2"
|
||||
|
||||
# Vérifie le contenu pickle
|
||||
with open(temp_home / ".slic" / "secrets", "rb") as f:
|
||||
data = pickle.load(f)
|
||||
assert data == {
|
||||
"first_key": "first_value",
|
||||
"second_key": "second_value"
|
||||
}
|
||||
assert data == {"db_user": "pass1", "db_pass": "pass2"}
|
||||
|
||||
def test_keyboard_interrupt(self, secrets_dir, monkeypatch, capsys):
|
||||
"""Test l'annulation avec Ctrl+C"""
|
||||
monkeypatch.setattr("mon_module.DotDir", lambda: lambda _: str(secrets_dir / "secrets"))
|
||||
|
||||
def test_keyboard_interrupt(self, temp_home, capsys):
|
||||
"""Test l'annulation par Ctrl+C"""
|
||||
secrets = Secrets()
|
||||
|
||||
# Simule Ctrl+C
|
||||
with patch("getpass.getpass", side_effect=KeyboardInterrupt):
|
||||
secrets.set("canceled_key")
|
||||
|
||||
# Vérifie qu'aucun fichier n'a été créé pour cette annulation
|
||||
assert not (secrets_dir / "secrets").exists()
|
||||
# Vérifie qu'aucun fichier n'a été créé
|
||||
assert not (temp_home / ".slic" / "secrets").exists()
|
||||
captured = capsys.readouterr()
|
||||
assert captured.out == "\n"
|
||||
|
||||
assert captured.out == "\n" # Saut de ligne du print()
|
||||
Reference in New Issue
Block a user