import pytest from cryptography.fernet import Fernet class TestKeyEncryptionBasic: """基础加密解密测试""" def test_encrypt_decrypt_roundtrip(self): from app.services.key_encryption import KeyEncryption encryption = KeyEncryption(encryption_key="test-key-for-encryption-12345") plaintext = "sk-1234567890abcdef" ciphertext = encryption.encrypt(plaintext) decrypted = encryption.decrypt(ciphertext) assert decrypted == plaintext def test_encrypted_content_differs_from_plaintext(self): from app.services.key_encryption import KeyEncryption encryption = KeyEncryption(encryption_key="test-key-for-encryption-12345") plaintext = "sk-1234567890abcdef" ciphertext = encryption.encrypt(plaintext) assert ciphertext != plaintext assert ciphertext != plaintext.encode() def test_same_plaintext_produces_different_ciphertext(self): from app.services.key_encryption import KeyEncryption encryption = KeyEncryption(encryption_key="test-key-for-encryption-12345") plaintext = "sk-1234567890abcdef" ciphertext1 = encryption.encrypt(plaintext) ciphertext2 = encryption.encrypt(plaintext) assert ciphertext1 != ciphertext2 class TestKeyEncryptionEdgeCases: """边界情况测试""" def test_encrypt_empty_string_raises_error(self): from app.services.key_encryption import KeyEncryption encryption = KeyEncryption(encryption_key="test-key-for-encryption-12345") with pytest.raises(ValueError, match="Cannot encrypt empty string"): encryption.encrypt("") def test_decrypt_empty_string_raises_error(self): from app.services.key_encryption import KeyEncryption encryption = KeyEncryption(encryption_key="test-key-for-encryption-12345") with pytest.raises(ValueError, match="Cannot decrypt empty string"): encryption.decrypt("") def test_encrypt_special_characters(self): from app.services.key_encryption import KeyEncryption encryption = KeyEncryption(encryption_key="test-key-for-encryption-12345") plaintext = "sk-中文测试!@#$%^&*()_+-=[]{}|;':\",./<>?" ciphertext = encryption.encrypt(plaintext) decrypted = encryption.decrypt(ciphertext) assert decrypted == plaintext def test_encrypt_unicode_characters(self): from app.services.key_encryption import KeyEncryption encryption = KeyEncryption(encryption_key="test-key-for-encryption-12345") plaintext = "sk-日本語テスト한국어" ciphertext = encryption.encrypt(plaintext) decrypted = encryption.decrypt(ciphertext) assert decrypted == plaintext class TestKeyEncryptionInvalidInputs: """无效输入测试""" def test_decrypt_invalid_ciphertext_raises_error(self): from app.services.key_encryption import KeyEncryption encryption = KeyEncryption(encryption_key="test-key-for-encryption-12345") with pytest.raises(ValueError, match="Invalid ciphertext or key"): encryption.decrypt("invalid-ciphertext-that-cannot-be-decrypted") def test_decrypt_with_wrong_key_raises_error(self): from app.services.key_encryption import KeyEncryption encryption1 = KeyEncryption(encryption_key="key-one-for-encryption-1234") encryption2 = KeyEncryption(encryption_key="key-two-for-encryption-1234") plaintext = "sk-1234567890abcdef" ciphertext = encryption1.encrypt(plaintext) with pytest.raises(ValueError, match="Invalid ciphertext or key"): encryption2.decrypt(ciphertext) class TestKeyEncryptionKeyFormats: """密钥格式测试""" def test_valid_fernet_key_format(self): from app.services.key_encryption import KeyEncryption valid_key = Fernet.generate_key().decode() encryption = KeyEncryption(encryption_key=valid_key) plaintext = "sk-1234567890abcdef" ciphertext = encryption.encrypt(plaintext) decrypted = encryption.decrypt(ciphertext) assert decrypted == plaintext def test_password_based_key_derivation(self): from app.services.key_encryption import KeyEncryption password = "my-secret-password-12345" encryption = KeyEncryption(encryption_key=password) plaintext = "sk-1234567890abcdef" ciphertext = encryption.encrypt(plaintext) decrypted = encryption.decrypt(ciphertext) assert decrypted == plaintext class TestKeyEncryptionSingleton: """全局实例测试""" def test_get_key_encryption_returns_instance(self): from app.services.key_encryption import get_key_encryption instance = get_key_encryption() assert instance is not None assert hasattr(instance, "encrypt") assert hasattr(instance, "decrypt") def test_reset_key_encryption_clears_singleton(self): from app.services.key_encryption import get_key_encryption, reset_key_encryption instance1 = get_key_encryption() reset_key_encryption() instance2 = get_key_encryption() assert instance1 is not instance2 class TestAPIKeyManagerEncryption: """APIKeyManager集成测试""" def test_api_key_manager_uses_fernet_encryption(self): from app.services.api_key_manager import APIKeyManager manager = APIKeyManager() original_key = "sk-1234567890abcdef" config = manager.add_key("chatgpt", original_key) assert config.encrypted_key != original_key assert not config.encrypted_key.startswith("sk-") decrypted = manager.get_key("chatgpt") assert decrypted == original_key def test_encrypted_key_is_not_base64_of_plaintext(self): from app.services.api_key_manager import APIKeyManager import base64 manager = APIKeyManager() original_key = "sk-1234567890abcdef" config = manager.add_key("chatgpt", original_key) plain_base64 = base64.b64encode(original_key.encode()).decode() assert config.encrypted_key != plain_base64