Files
pvemanager/backend/tests/test_crypto.py
markmorado 89d70654fc fix(reinstall): use OSTemplate.vmid (not template_vmid) and convert memory bytes->MB
- AttributeError: OSTemplate has no 'template_vmid' field; the actual column is 'vmid'.
- Use OSTemplate.get_vmid_for_node() to support cross-node replicated templates,
  falling back to source_node/vmid otherwise.
- VMInstance.memory is stored in bytes, but Proxmox config expects MB.
2026-04-29 23:48:48 +02:00

70 lines
2.6 KiB
Python

"""Smoke tests for ``app.crypto`` field-level encryption helpers."""
from __future__ import annotations
import importlib
import pytest
@pytest.fixture(scope="module")
def crypto():
return importlib.import_module("app.crypto")
class TestEncryptDecryptRoundtrip:
@pytest.mark.smoke
def test_roundtrip_simple_string(self, crypto):
token = crypto.encrypt_value("hunter2")
assert token != "hunter2"
assert crypto.decrypt_value(token) == "hunter2"
@pytest.mark.smoke
def test_roundtrip_unicode(self, crypto):
secret = "пароль-密码-🔐"
assert crypto.decrypt_value(crypto.encrypt_value(secret)) == secret
def test_empty_value_passthrough(self, crypto):
assert crypto.encrypt_value("") == ""
assert crypto.decrypt_value("") == ""
assert crypto.encrypt_value(None) is None
assert crypto.decrypt_value(None) is None
def test_each_call_produces_unique_ciphertext(self, crypto):
# Fernet embeds a random IV — same plaintext should encrypt differently.
a = crypto.encrypt_value("same")
b = crypto.encrypt_value("same")
assert a != b
assert crypto.decrypt_value(a) == crypto.decrypt_value(b) == "same"
class TestLegacyPlaintextFallback:
def test_decrypt_invalid_token_returns_input(self, crypto):
# Legacy/un-encrypted rows must not blow up — fall through to plaintext.
assert crypto.decrypt_value("plain-value-not-fernet") == "plain-value-not-fernet"
class TestNoFernetKey:
def test_encrypt_passthrough_without_key(self, crypto, monkeypatch):
# ``settings`` is imported lazily inside ``_get_fernet`` — patch the live
# singleton on the config module instead.
from app import config as app_config
monkeypatch.setattr(app_config.settings, "FERNET_KEY", None, raising=False)
monkeypatch.setattr(crypto, "_warned_no_key", False, raising=False)
assert crypto.encrypt_value("plain") == "plain"
assert crypto.decrypt_value("plain") == "plain"
class TestEncryptedStringColumn:
def test_bind_and_result_processors(self, crypto):
col = crypto.EncryptedString(255)
bound = col.process_bind_param("topsecret", dialect=None)
assert bound != "topsecret"
assert col.process_result_value(bound, dialect=None) == "topsecret"
def test_bind_and_result_handle_none(self, crypto):
col = crypto.EncryptedString(255)
assert col.process_bind_param(None, dialect=None) is None
assert col.process_result_value(None, dialect=None) is None