wrongmove/tests/unit/test_passkey_error_handling.py

72 lines
3 KiB
Python
Raw Normal View History

"""Unit tests for passkey route error handling."""
from unittest.mock import patch, MagicMock
import pytest
from starlette.testclient import TestClient
# We need to test through the FastAPI app or build a minimal test client
from api.passkey_routes import passkey_router
from fastapi import FastAPI
def _build_app() -> FastAPI:
app = FastAPI()
app.include_router(passkey_router)
return app
class TestPasskeyErrorHandling:
"""Tests that passkey routes return generic error messages for internal exceptions."""
@patch("api.passkey_routes.passkey_service")
@patch("api.passkey_routes.UserRepository")
def test_register_begin_internal_error_returns_generic_message(
self, mock_user_repo: MagicMock, mock_service: MagicMock
) -> None:
mock_service.begin_registration.side_effect = RuntimeError("DB connection lost")
client = TestClient(_build_app())
resp = client.post("/api/passkey/register/begin", json={"email": "test@example.com"})
assert resp.status_code == 400
assert resp.json()["detail"] == "Registration failed. Please try again."
assert "DB connection lost" not in resp.json()["detail"]
@patch("api.passkey_routes.passkey_service")
@patch("api.passkey_routes.UserRepository")
def test_register_begin_value_error_returns_user_message(
self, mock_user_repo: MagicMock, mock_service: MagicMock
) -> None:
mock_service.begin_registration.side_effect = ValueError("Email already registered")
client = TestClient(_build_app())
resp = client.post("/api/passkey/register/begin", json={"email": "test@example.com"})
assert resp.status_code == 400
assert resp.json()["detail"] == "Email already registered"
@patch("api.passkey_routes.passkey_service")
@patch("api.passkey_routes.UserRepository")
def test_login_complete_internal_error_returns_generic_message(
self, mock_user_repo: MagicMock, mock_service: MagicMock
) -> None:
mock_service.complete_authentication.side_effect = RuntimeError("Crypto failure")
client = TestClient(_build_app())
resp = client.post(
"/api/passkey/login/complete",
json={"session_id": "abc", "credential": {"id": "x"}},
)
assert resp.status_code == 400
assert resp.json()["detail"] == "Login could not be completed."
assert "Crypto failure" not in resp.json()["detail"]
@patch("api.passkey_routes.passkey_service")
@patch("api.passkey_routes.UserRepository")
def test_login_complete_value_error_returns_user_message(
self, mock_user_repo: MagicMock, mock_service: MagicMock
) -> None:
mock_service.complete_authentication.side_effect = ValueError("Invalid credential")
client = TestClient(_build_app())
resp = client.post(
"/api/passkey/login/complete",
json={"session_id": "abc", "credential": {"id": "x"}},
)
assert resp.status_code == 400
assert resp.json()["detail"] == "Invalid credential"