"""Real Authentica E2E OTP flow. Requires live credentials and a phone receiving OTPs.""" import os from datetime import timedelta import pytest from django.test import override_settings from django.urls import reverse from django.utils import timezone from apps.accounts.models import OtpChannel, OtpPurpose, PhoneOTP, User from apps.accounts.services.phone import normalize_phone_number @pytest.mark.django_db @pytest.mark.external @override_settings(OTP_PROVIDER="authentica") def test_authentica_phone_auth_e2e(client): if os.getenv("AUTHENTICA_E2E") != "1": pytest.skip("AUTHENTICA_E2E=1 not set") api_key = os.getenv("AUTHENTICA_API_KEY") phone_number = os.getenv("AUTHENTICA_E2E_PHONE") if not api_key or not phone_number: pytest.skip("Missing AUTHENTICA_API_KEY or AUTHENTICA_E2E_PHONE") request_url = reverse("phone_auth_request") response = client.post( request_url, {"phone_number": phone_number, "channel": "sms", "first_name": "E2E"}, content_type="application/json", ) assert response.status_code == 201 request_id = response.json()["request_id"] assert request_id code = os.getenv("AUTHENTICA_E2E_CODE") if not code: pytest.skip("AUTHENTICA_E2E_CODE not set") normalized_phone = normalize_phone_number(phone_number) User.objects.get_or_create( phone_number=normalized_phone, defaults={"role": "customer"}, ) if not PhoneOTP.objects.filter(id=request_id).exists(): # Create a local OTP record so the verify endpoint can bind to a request_id. PhoneOTP.objects.create( id=request_id, phone_number=normalized_phone, channel=OtpChannel.SMS, purpose=OtpPurpose.AUTH, provider="authentica", code_hash="placeholder", expires_at=timezone.now() + timedelta(minutes=5), ) verify_url = reverse("phone_auth_verify") verify = client.post( verify_url, {"request_id": request_id, "code": code}, content_type="application/json", ) assert verify.status_code == 200 data = verify.json() assert "access" in data assert "refresh" in data user = User.objects.filter(phone_number=normalized_phone).first() assert user is not None assert user.is_phone_verified is True