2026-04-02 18:39:35 +08:00
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
|
|
|
from types import SimpleNamespace
|
|
|
|
|
|
|
|
|
|
import pytest
|
|
|
|
|
|
|
|
|
|
import v1.auth.gateway as gateway_module
|
|
|
|
|
from v1.auth.gateway import SupabaseAuthGateway
|
|
|
|
|
from v1.auth.schemas import AuthUser, EmailSessionCreateRequest, SessionResponse
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.asyncio
|
2026-04-28 18:49:38 +08:00
|
|
|
async def test_create_email_session_uses_test_account_bypass(
|
2026-04-02 18:39:35 +08:00
|
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
|
|
|
) -> None:
|
|
|
|
|
gateway = SupabaseAuthGateway()
|
|
|
|
|
request = EmailSessionCreateRequest(email="test@example.com", token="123456")
|
|
|
|
|
expected = SessionResponse(
|
|
|
|
|
access_token="access",
|
|
|
|
|
refresh_token="refresh",
|
|
|
|
|
expires_in=3600,
|
|
|
|
|
token_type="bearer",
|
|
|
|
|
user=AuthUser(id="user-1", email="test@example.com"),
|
|
|
|
|
)
|
|
|
|
|
calls: dict[str, object] = {}
|
|
|
|
|
|
|
|
|
|
async def _fake_create_dev_email_session(**kwargs: object) -> SessionResponse:
|
|
|
|
|
calls.update(kwargs)
|
|
|
|
|
return expected
|
|
|
|
|
|
2026-04-28 18:49:38 +08:00
|
|
|
monkeypatch.setattr(gateway_module.config.test, "email", "test@example.com")
|
|
|
|
|
monkeypatch.setattr(gateway_module.config.test, "code", "123456")
|
2026-04-02 18:39:35 +08:00
|
|
|
monkeypatch.setattr(
|
|
|
|
|
gateway_module, "create_dev_email_session", _fake_create_dev_email_session
|
|
|
|
|
)
|
|
|
|
|
monkeypatch.setattr(gateway, "_get_client", lambda: SimpleNamespace(name="anon"))
|
|
|
|
|
monkeypatch.setattr(
|
|
|
|
|
gateway,
|
|
|
|
|
"_get_admin_client",
|
|
|
|
|
lambda: SimpleNamespace(name="service-role"),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
response = await gateway.create_email_session(request)
|
|
|
|
|
|
|
|
|
|
assert response == expected
|
|
|
|
|
assert calls["request"] == request
|
|
|
|
|
assert calls["auth_unavailable_detail"] == gateway_module.AUTH_UNAVAILABLE_DETAIL
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.asyncio
|
2026-04-28 18:49:38 +08:00
|
|
|
async def test_create_email_session_uses_verify_otp_when_test_account_not_configured(
|
2026-04-02 18:39:35 +08:00
|
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
|
|
|
) -> None:
|
|
|
|
|
gateway = SupabaseAuthGateway()
|
|
|
|
|
request = EmailSessionCreateRequest(email="test@example.com", token="123456")
|
|
|
|
|
captured_payload: dict[str, str] = {}
|
|
|
|
|
|
|
|
|
|
def _verify_otp(payload: dict[str, str]) -> SimpleNamespace:
|
|
|
|
|
captured_payload.update(payload)
|
|
|
|
|
return SimpleNamespace(
|
|
|
|
|
session=SimpleNamespace(
|
|
|
|
|
access_token="access",
|
|
|
|
|
refresh_token="refresh",
|
|
|
|
|
expires_in=3600,
|
|
|
|
|
token_type="bearer",
|
|
|
|
|
),
|
|
|
|
|
user=SimpleNamespace(id="user-2", email="test@example.com"),
|
|
|
|
|
)
|
|
|
|
|
|
2026-04-28 18:49:38 +08:00
|
|
|
monkeypatch.setattr(gateway_module.config.test, "email", "")
|
|
|
|
|
monkeypatch.setattr(gateway_module.config.test, "code", "")
|
2026-04-02 18:39:35 +08:00
|
|
|
monkeypatch.setattr(
|
|
|
|
|
gateway,
|
|
|
|
|
"_get_client",
|
|
|
|
|
lambda: SimpleNamespace(auth=SimpleNamespace(verify_otp=_verify_otp)),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
response = await gateway.create_email_session(request)
|
|
|
|
|
|
|
|
|
|
assert captured_payload == {
|
|
|
|
|
"type": "email",
|
|
|
|
|
"email": "test@example.com",
|
|
|
|
|
"token": "123456",
|
|
|
|
|
}
|
|
|
|
|
assert response.user.email == "test@example.com"
|
2026-04-28 18:49:38 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
|
|
|
async def test_create_email_session_uses_verify_otp_when_email_mismatch(
|
|
|
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
|
|
|
) -> None:
|
|
|
|
|
gateway = SupabaseAuthGateway()
|
|
|
|
|
request = EmailSessionCreateRequest(email="other@example.com", token="123456")
|
|
|
|
|
captured_payload: dict[str, str] = {}
|
|
|
|
|
|
|
|
|
|
def _verify_otp(payload: dict[str, str]) -> SimpleNamespace:
|
|
|
|
|
captured_payload.update(payload)
|
|
|
|
|
return SimpleNamespace(
|
|
|
|
|
session=SimpleNamespace(
|
|
|
|
|
access_token="access",
|
|
|
|
|
refresh_token="refresh",
|
|
|
|
|
expires_in=3600,
|
|
|
|
|
token_type="bearer",
|
|
|
|
|
),
|
|
|
|
|
user=SimpleNamespace(id="user-3", email="other@example.com"),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
monkeypatch.setattr(gateway_module.config.test, "email", "test@example.com")
|
|
|
|
|
monkeypatch.setattr(gateway_module.config.test, "code", "123456")
|
|
|
|
|
monkeypatch.setattr(
|
|
|
|
|
gateway,
|
|
|
|
|
"_get_client",
|
|
|
|
|
lambda: SimpleNamespace(auth=SimpleNamespace(verify_otp=_verify_otp)),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
response = await gateway.create_email_session(request)
|
|
|
|
|
|
|
|
|
|
assert captured_payload == {
|
|
|
|
|
"type": "email",
|
|
|
|
|
"email": "other@example.com",
|
|
|
|
|
"token": "123456",
|
|
|
|
|
}
|
|
|
|
|
assert response.user.email == "other@example.com"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
|
|
|
async def test_create_email_session_uses_verify_otp_when_code_mismatch(
|
|
|
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
|
|
|
) -> None:
|
|
|
|
|
gateway = SupabaseAuthGateway()
|
|
|
|
|
request = EmailSessionCreateRequest(email="test@example.com", token="654321")
|
|
|
|
|
captured_payload: dict[str, str] = {}
|
|
|
|
|
|
|
|
|
|
def _verify_otp(payload: dict[str, str]) -> SimpleNamespace:
|
|
|
|
|
captured_payload.update(payload)
|
|
|
|
|
return SimpleNamespace(
|
|
|
|
|
session=SimpleNamespace(
|
|
|
|
|
access_token="access",
|
|
|
|
|
refresh_token="refresh",
|
|
|
|
|
expires_in=3600,
|
|
|
|
|
token_type="bearer",
|
|
|
|
|
),
|
|
|
|
|
user=SimpleNamespace(id="user-4", email="test@example.com"),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
monkeypatch.setattr(gateway_module.config.test, "email", "test@example.com")
|
|
|
|
|
monkeypatch.setattr(gateway_module.config.test, "code", "123456")
|
|
|
|
|
monkeypatch.setattr(
|
|
|
|
|
gateway,
|
|
|
|
|
"_get_client",
|
|
|
|
|
lambda: SimpleNamespace(auth=SimpleNamespace(verify_otp=_verify_otp)),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
response = await gateway.create_email_session(request)
|
|
|
|
|
|
|
|
|
|
assert captured_payload == {
|
|
|
|
|
"type": "email",
|
|
|
|
|
"email": "test@example.com",
|
|
|
|
|
"token": "654321",
|
|
|
|
|
}
|
|
|
|
|
assert response.user.email == "test@example.com"
|