Files
simbarag/tests/unit/test_crypto_service.py
2026-04-04 08:48:45 -04:00

92 lines
3.2 KiB
Python

"""Tests for encryption/decryption in blueprints/email/crypto_service.py."""
import os
from unittest.mock import patch
import pytest
from cryptography.fernet import Fernet
# Generate a valid key for testing
TEST_FERNET_KEY = Fernet.generate_key().decode()
class TestEncryptedTextField:
@pytest.fixture
def field(self):
with patch.dict(os.environ, {"FERNET_KEY": TEST_FERNET_KEY}):
from blueprints.email.crypto_service import EncryptedTextField
return EncryptedTextField()
def test_encrypt_decrypt_roundtrip(self, field):
original = "my secret password"
encrypted = field.to_db_value(original, None)
decrypted = field.to_python_value(encrypted)
assert decrypted == original
assert encrypted != original
def test_none_passthrough(self, field):
assert field.to_db_value(None, None) is None
assert field.to_python_value(None) is None
def test_unicode_roundtrip(self, field):
original = "Hello 世界 🐱"
encrypted = field.to_db_value(original, None)
decrypted = field.to_python_value(encrypted)
assert decrypted == original
def test_empty_string_roundtrip(self, field):
encrypted = field.to_db_value("", None)
decrypted = field.to_python_value(encrypted)
assert decrypted == ""
def test_long_text_roundtrip(self, field):
original = "x" * 10000
encrypted = field.to_db_value(original, None)
decrypted = field.to_python_value(encrypted)
assert decrypted == original
def test_different_encryptions_differ(self, field):
"""Fernet includes a timestamp, so two encryptions of the same value differ."""
e1 = field.to_db_value("same", None)
e2 = field.to_db_value("same", None)
assert e1 != e2 # Different ciphertexts
assert field.to_python_value(e1) == field.to_python_value(e2) == "same"
def test_wrong_key_fails(self, field):
encrypted = field.to_db_value("secret", None)
# Create a field with a different key
other_key = Fernet.generate_key().decode()
with patch.dict(os.environ, {"FERNET_KEY": other_key}):
from blueprints.email.crypto_service import EncryptedTextField
other_field = EncryptedTextField()
with pytest.raises(Exception):
other_field.to_python_value(encrypted)
class TestValidateFernetKey:
def test_valid_key(self):
with patch.dict(os.environ, {"FERNET_KEY": TEST_FERNET_KEY}):
from blueprints.email.crypto_service import validate_fernet_key
validate_fernet_key() # Should not raise
def test_missing_key(self):
with patch.dict(os.environ, {}, clear=True):
os.environ.pop("FERNET_KEY", None)
from blueprints.email.crypto_service import validate_fernet_key
with pytest.raises(ValueError, match="not set"):
validate_fernet_key()
def test_invalid_key(self):
with patch.dict(os.environ, {"FERNET_KEY": "not-a-valid-key"}):
from blueprints.email.crypto_service import validate_fernet_key
with pytest.raises(ValueError, match="validation failed"):
validate_fernet_key()