test_mfa_helpers.py 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. """Unit tests for 2FA helper functions in mfa.py."""
  2. import base64
  3. import string
  4. import pytest
  5. from passlib.context import CryptContext
  6. from backend.app.api.routes.mfa import _generate_backup_codes, _generate_totp_qr_b64
  7. class TestBackupCodeGeneration:
  8. """Tests for backup code helpers."""
  9. def test_generates_ten_codes(self):
  10. plain, hashed = _generate_backup_codes()
  11. assert len(plain) == 10
  12. assert len(hashed) == 10
  13. def test_codes_are_eight_chars(self):
  14. plain, _ = _generate_backup_codes()
  15. for code in plain:
  16. assert len(code) == 8
  17. def test_codes_are_alphanumeric(self):
  18. allowed = set(string.ascii_uppercase + string.digits)
  19. plain, _ = _generate_backup_codes()
  20. for code in plain:
  21. assert all(c in allowed for c in code)
  22. def test_hashes_verify_against_plain(self):
  23. ctx = CryptContext(schemes=["pbkdf2_sha256"], deprecated="auto")
  24. plain, hashed = _generate_backup_codes()
  25. for p, h in zip(plain, hashed, strict=True):
  26. assert ctx.verify(p, h)
  27. def test_codes_are_unique(self):
  28. plain, _ = _generate_backup_codes()
  29. assert len(set(plain)) == 10
  30. class TestTOTPQRCode:
  31. """Tests for QR code generation helper."""
  32. def test_generates_base64_png(self):
  33. uri = "otpauth://totp/Bambuddy:testuser?secret=BASE32SECRET&issuer=Bambuddy"
  34. result = _generate_totp_qr_b64(uri)
  35. decoded = base64.b64decode(result)
  36. assert decoded[:4] == b"\x89PNG"