feat: phone auth tests and fixes
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
from django.urls import reverse
|
||||
|
||||
from apps.accounts.models import OtpPurpose, PhoneOTP, User
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_create_user_rejects_email_only_identity():
|
||||
# Phone-first invariant: do not allow creating users without phone_number.
|
||||
with pytest.raises(ValueError):
|
||||
User.objects.create_user(email="email-only@example.com")
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_register_requires_phone_number(client):
|
||||
# Public registration must keep phone as required identifier.
|
||||
response = client.post(
|
||||
reverse("register"),
|
||||
{"email": "new@example.com", "password": "StrongPass123"},
|
||||
content_type="application/json",
|
||||
)
|
||||
|
||||
assert response.status_code == 400
|
||||
assert "phone_number" in response.json()
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_phone_auth_verify_rejects_verify_purpose_otp(client):
|
||||
user = User.objects.create_user(phone_number="+966512345678")
|
||||
otp = PhoneOTP.objects.create(
|
||||
phone_number=user.phone_number,
|
||||
channel="sms",
|
||||
purpose=OtpPurpose.VERIFY,
|
||||
provider="console",
|
||||
code_hash="not-used",
|
||||
expires_at=PhoneOTP.expiry_at(),
|
||||
)
|
||||
|
||||
# Purpose boundary: /phone/verify must only accept auth OTP requests.
|
||||
with patch("apps.accounts.views.verify_otp", return_value=True):
|
||||
response = client.post(
|
||||
reverse("phone_auth_verify"),
|
||||
{"request_id": str(otp.id), "code": "123456"},
|
||||
content_type="application/json",
|
||||
)
|
||||
|
||||
assert response.status_code == 400
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_otp_verify_rejects_auth_purpose_otp(client):
|
||||
otp = PhoneOTP.objects.create(
|
||||
phone_number="+966512345678",
|
||||
channel="sms",
|
||||
purpose=OtpPurpose.AUTH,
|
||||
provider="console",
|
||||
code_hash="not-used",
|
||||
expires_at=PhoneOTP.expiry_at(),
|
||||
)
|
||||
|
||||
# Purpose boundary: /otp/verify must only accept verify OTP requests.
|
||||
with patch("apps.accounts.views.verify_otp", return_value=True):
|
||||
response = client.post(
|
||||
reverse("otp_verify"),
|
||||
{"request_id": str(otp.id), "code": "123456"},
|
||||
content_type="application/json",
|
||||
)
|
||||
|
||||
assert response.status_code == 400
|
||||
Reference in New Issue
Block a user