Authentica OTP tests
This commit is contained in:
@@ -1,13 +1,49 @@
|
||||
import pytest
|
||||
from django.contrib.auth.hashers import make_password
|
||||
from django.test import override_settings
|
||||
|
||||
from apps.accounts.models import OtpChannel
|
||||
from apps.accounts.services.otp import OtpRateLimitError, create_and_send_otp
|
||||
from apps.accounts.models import OtpChannel, OtpPurpose, PhoneOTP
|
||||
from apps.accounts.services.otp import OtpCooldownError, OtpRateLimitError, create_and_send_otp, verify_otp
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
@override_settings(OTP_MAX_PER_WINDOW=1, OTP_WINDOW_MINUTES=15, OTP_RESEND_COOLDOWN_SECONDS=0)
|
||||
@override_settings(OTP_PROVIDER="console", OTP_MAX_PER_WINDOW=1, OTP_WINDOW_MINUTES=15, OTP_RESEND_COOLDOWN_SECONDS=0)
|
||||
def test_otp_rate_limit():
|
||||
create_and_send_otp("+966512345678", OtpChannel.SMS)
|
||||
with pytest.raises(OtpRateLimitError):
|
||||
create_and_send_otp("+966512345678", OtpChannel.SMS)
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
@override_settings(
|
||||
OTP_PROVIDER="console",
|
||||
OTP_MAX_PER_WINDOW=5,
|
||||
OTP_WINDOW_MINUTES=15,
|
||||
OTP_RESEND_COOLDOWN_SECONDS=60,
|
||||
)
|
||||
def test_otp_cooldown_enforced():
|
||||
create_and_send_otp("+966512345678", OtpChannel.SMS)
|
||||
with pytest.raises(OtpCooldownError):
|
||||
create_and_send_otp("+966512345678", OtpChannel.SMS)
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_otp_max_attempts_blocks_verification():
|
||||
otp = PhoneOTP.objects.create(
|
||||
phone_number="+966512345678",
|
||||
channel=OtpChannel.SMS,
|
||||
purpose=OtpPurpose.AUTH,
|
||||
provider="console",
|
||||
code_hash=make_password("123456"),
|
||||
expires_at=PhoneOTP.expiry_at(),
|
||||
)
|
||||
# Burn attempts with wrong code until the limit is exceeded.
|
||||
for _ in range(otp.max_attempts):
|
||||
assert verify_otp(otp, "000000") is False
|
||||
otp.refresh_from_db()
|
||||
assert otp.attempt_count == otp.max_attempts
|
||||
|
||||
assert verify_otp(otp, "123456") is False
|
||||
otp.refresh_from_db()
|
||||
assert otp.attempt_count == otp.max_attempts + 1
|
||||
assert otp.verified_at is None
|
||||
|
||||
Reference in New Issue
Block a user