import base64 import hashlib import pytest from fastapi import HTTPException from app.core.config import get_settings from app.core.field_crypto import decrypt_text, encrypt_text from app.core.masking import mask_id_card, mask_mobile _ID_CARD = "620102199001011234" _MOBILE = "13800138000" def _use_key(monkeypatch, encoded: str) -> None: monkeypatch.setenv("FIELD_AES_KEY", encoded) get_settings.cache_clear() def test_id_card_and_mobile_roundtrip(monkeypatch): key = hashlib.sha256(b"field-crypto-test").digest() assert len(key) == 32 _use_key(monkeypatch, base64.b64encode(key).decode("ascii")) try: token = encrypt_text(_ID_CARD) assert token assert token != _ID_CARD assert decrypt_text(token) == _ID_CARD assert mask_id_card(decrypt_text(token)) == "6201**********1234" assert mask_id_card(_ID_CARD) == "6201**********1234" mobile_token = encrypt_text(_MOBILE) assert decrypt_text(mobile_token) == _MOBILE assert mask_mobile(_MOBILE) == "138****8000" assert encrypt_text("") == "" assert decrypt_text("") == "" finally: get_settings.cache_clear() def test_missing_or_short_field_key(monkeypatch): try: _use_key(monkeypatch, "") assert encrypt_text("") == "" with pytest.raises(HTTPException) as missing: encrypt_text(_ID_CARD) assert missing.value.status_code == 503 assert missing.value.detail == "字段加密未配置" short_key = base64.b64encode(b"0123456789abcdef").decode("ascii") _use_key(monkeypatch, short_key) with pytest.raises(HTTPException) as short: encrypt_text(_ID_CARD) assert short.value.status_code == 503 assert short.value.detail == "字段加密未配置" finally: get_settings.cache_clear()