Revamp authentication routes structure (#201)

* Fix #68: use makefun to generate dynamic dependencies

* Remove every Starlette imports

* Split every routers and remove event handlers

* Make users router optional

* Pass after_update handler to get_users_router

* Update documentation

* Remove test file

* Write migration doc for splitted routers
This commit is contained in:
François Voron
2020-05-24 10:18:01 +02:00
committed by GitHub
parent 0a0dcadfdc
commit 7721f8dcc1
48 changed files with 1633 additions and 1167 deletions

View File

@ -0,0 +1,122 @@
from typing import cast, Dict, Any
from unittest.mock import MagicMock
import asynctest
import httpx
import pytest
from fastapi import FastAPI, status, Request
from fastapi_users.router import ErrorCode, get_register_router
from tests.conftest import User, UserCreate, UserDB
SECRET = "SECRET"
LIFETIME = 3600
def after_register_sync():
return MagicMock(return_value=None)
def after_register_async():
return asynctest.CoroutineMock(return_value=None)
@pytest.fixture(params=[after_register_sync, after_register_async])
def after_register(request):
return request.param()
@pytest.fixture
@pytest.mark.asyncio
async def test_app_client(
mock_user_db, mock_authentication, after_register, get_test_client
) -> httpx.AsyncClient:
register_router = get_register_router(
mock_user_db, User, UserCreate, UserDB, after_register,
)
app = FastAPI()
app.include_router(register_router)
return await get_test_client(app)
@pytest.mark.router
@pytest.mark.asyncio
class TestRegister:
async def test_empty_body(self, test_app_client: httpx.AsyncClient, after_register):
response = await test_app_client.post("/register", json={})
assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY
assert after_register.called is False
async def test_missing_password(
self, test_app_client: httpx.AsyncClient, after_register
):
json = {"email": "king.arthur@camelot.bt"}
response = await test_app_client.post("/register", json=json)
assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY
assert after_register.called is False
async def test_wrong_email(
self, test_app_client: httpx.AsyncClient, after_register
):
json = {"email": "king.arthur", "password": "guinevere"}
response = await test_app_client.post("/register", json=json)
assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY
assert after_register.called is False
async def test_existing_user(
self, test_app_client: httpx.AsyncClient, after_register
):
json = {"email": "king.arthur@camelot.bt", "password": "guinevere"}
response = await test_app_client.post("/register", json=json)
assert response.status_code == status.HTTP_400_BAD_REQUEST
data = cast(Dict[str, Any], response.json())
assert data["detail"] == ErrorCode.REGISTER_USER_ALREADY_EXISTS
assert after_register.called is False
async def test_valid_body(self, test_app_client: httpx.AsyncClient, after_register):
json = {"email": "lancelot@camelot.bt", "password": "guinevere"}
response = await test_app_client.post("/register", json=json)
assert response.status_code == status.HTTP_201_CREATED
assert after_register.called is True
data = cast(Dict[str, Any], response.json())
assert "hashed_password" not in data
assert "password" not in data
assert data["id"] is not None
actual_user = after_register.call_args[0][0]
assert str(actual_user.id) == data["id"]
request = after_register.call_args[0][1]
assert isinstance(request, Request)
async def test_valid_body_is_superuser(
self, test_app_client: httpx.AsyncClient, after_register
):
json = {
"email": "lancelot@camelot.bt",
"password": "guinevere",
"is_superuser": True,
}
response = await test_app_client.post("/register", json=json)
assert response.status_code == status.HTTP_201_CREATED
assert after_register.called is True
data = cast(Dict[str, Any], response.json())
assert data["is_superuser"] is False
async def test_valid_body_is_active(
self, test_app_client: httpx.AsyncClient, after_register
):
json = {
"email": "lancelot@camelot.bt",
"password": "guinevere",
"is_active": False,
}
response = await test_app_client.post("/register", json=json)
assert response.status_code == status.HTTP_201_CREATED
assert after_register.called is True
data = cast(Dict[str, Any], response.json())
assert data["is_active"] is True