Add a name on every route #762 (#774)

* Names for urls added

* Tests for Login/Logout Names

* Register Name Test

* tests/test_router_reset.py

* Tests to verify url names in users router

* Test Verify Router Names

* oauth routes updated with prefix

* Test for authorize.  Didn't right test for callback as covered under other tests
This commit is contained in:
Brandon H. Goding
2021-11-02 03:12:43 -04:00
committed by GitHub
parent e0e8dfbc3b
commit 0c45cbc179
12 changed files with 137 additions and 11 deletions

View File

@ -19,7 +19,7 @@ def get_auth_router(
active=True, verified=requires_verification
)
@router.post("/login")
@router.post("/login", name="auth:login")
async def login(
response: Response,
credentials: OAuth2PasswordRequestForm = Depends(),
@ -41,7 +41,7 @@ def get_auth_router(
if backend.logout:
@router.post("/logout")
@router.post("/logout", name="auth:logout")
async def logout(
response: Response,
user=Depends(get_current_user),

View File

@ -30,7 +30,7 @@ def get_oauth_router(
) -> APIRouter:
"""Generate a router with the OAuth routes."""
router = APIRouter()
callback_route_name = f"{oauth_client.name}-callback"
callback_route_name = f"oauth:{oauth_client.name}-callback"
if redirect_url is not None:
oauth2_authorize_callback = OAuth2AuthorizeCallback(
@ -43,7 +43,7 @@ def get_oauth_router(
route_name=callback_route_name,
)
@router.get("/authorize")
@router.get("/authorize", name="oauth:authorize")
async def authorize(
request: Request,
authentication_backend: str,
@ -74,7 +74,7 @@ def get_oauth_router(
return {"authorization_url": authorization_url}
@router.get("/callback", name=f"{oauth_client.name}-callback")
@router.get("/callback", name=f"oauth:{oauth_client.name}-callback")
async def callback(
request: Request,
response: Response,

View File

@ -21,7 +21,7 @@ def get_register_router(
router = APIRouter()
@router.post(
"/register", response_model=user_model, status_code=status.HTTP_201_CREATED
"/register", response_model=user_model, status_code=status.HTTP_201_CREATED, name="register:register"
)
async def register(
request: Request,

View File

@ -19,7 +19,7 @@ def get_reset_password_router(
"""Generate a router with the reset password routes."""
router = APIRouter()
@router.post("/forgot-password", status_code=status.HTTP_202_ACCEPTED)
@router.post("/forgot-password", status_code=status.HTTP_202_ACCEPTED, name="reset:forgot_password")
async def forgot_password(
request: Request,
email: EmailStr = Body(..., embed=True),
@ -37,7 +37,7 @@ def get_reset_password_router(
return None
@router.post("/reset-password")
@router.post("/reset-password", name="reset:reset_password")
async def reset_password(
request: Request,
token: str = Body(...),

View File

@ -42,7 +42,7 @@ def get_users_router(
except UserNotExists:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)
@router.get("/me", response_model=user_model)
@router.get("/me", response_model=user_model, name="users:current_user")
async def me(
user: user_db_model = Depends(get_current_active_user), # type: ignore
):
@ -52,6 +52,7 @@ def get_users_router(
"/me",
response_model=user_model,
dependencies=[Depends(get_current_active_user)],
name="users:current_user"
)
async def update_me(
request: Request,
@ -81,6 +82,7 @@ def get_users_router(
"/{id:uuid}",
response_model=user_model,
dependencies=[Depends(get_current_superuser)],
name="users:user"
)
async def get_user(user=Depends(get_user_or_404)):
return user
@ -89,6 +91,7 @@ def get_users_router(
"/{id:uuid}",
response_model=user_model,
dependencies=[Depends(get_current_superuser)],
name="users:user"
)
async def update_user(
user_update: user_update_model, # type: ignore
@ -119,6 +122,7 @@ def get_users_router(
status_code=status.HTTP_204_NO_CONTENT,
response_class=Response,
dependencies=[Depends(get_current_superuser)],
name="users:user"
)
async def delete_user(
user=Depends(get_user_or_404),

View File

@ -21,7 +21,7 @@ def get_verify_router(
):
router = APIRouter()
@router.post("/request-verify-token", status_code=status.HTTP_202_ACCEPTED)
@router.post("/request-verify-token", status_code=status.HTTP_202_ACCEPTED, name="verify:request-token")
async def request_verify_token(
request: Request,
email: EmailStr = Body(..., embed=True),
@ -35,7 +35,7 @@ def get_verify_router(
return None
@router.post("/verify", response_model=user_model)
@router.post("/verify", response_model=user_model, name="verify:verify")
async def verify(
request: Request,
token: str = Body(..., embed=True),

View File

@ -157,6 +157,16 @@ class TestLogin:
data = cast(Dict[str, Any], response.json())
assert data["detail"] == ErrorCode.LOGIN_BAD_CREDENTIALS
async def test_login_namespace(
self,
path,
app_factory
):
split_url = app_factory(True).url_path_for("auth:login").split("/")
assert split_url[len(split_url) - 1] in path
@pytest.mark.router
@pytest.mark.parametrize("path", ["/mock/logout", "/mock-bis/logout"])
@ -199,3 +209,11 @@ class TestLogout:
path, headers={"Authorization": f"Bearer {verified_user.id}"}
)
assert response.status_code == status.HTTP_200_OK
async def test_logout_namespace(
self,
path,
app_factory
):
split_url = app_factory(True).url_path_for("auth:logout").split("/")
assert split_url[len(split_url) - 1] in path

View File

@ -272,3 +272,31 @@ class TestCallback:
data = cast(Dict[str, Any], response.json())
assert data["token"] == str(user_oauth.id)
@pytest.mark.asyncio
async def test_oauth_authorize_namespace(
secret,
get_user_manager_oauth,
mock_authentication,
oauth_client,
get_test_client,
redirect_url: str = None,
):
mock_authentication_bis = MockAuthentication(name="mock-bis")
authenticator = Authenticator(
[mock_authentication, mock_authentication_bis], get_user_manager_oauth
)
app = FastAPI()
app.include_router(
get_oauth_router(
oauth_client,
get_user_manager_oauth,
authenticator,
secret,
redirect_url,
)
)
assert app.url_path_for("oauth:authorize") == "/authorize"

View File

@ -102,3 +102,18 @@ class TestRegister:
data = cast(Dict[str, Any], response.json())
assert data["is_active"] is True
@pytest.mark.asyncio
async def test_register_namespace(
get_user_manager
):
app = FastAPI()
app.include_router(
get_register_router(
get_user_manager,
User,
UserCreate,
)
)
assert app.url_path_for("register:register") == "/register"

View File

@ -148,3 +148,25 @@ class TestResetPassword:
json = {"token": "foo", "password": "guinevere"}
response = await test_app_client.post("/reset-password", json=json)
assert response.status_code == status.HTTP_200_OK
@pytest.mark.asyncio
async def test_forgot_password_namespace(
get_user_manager
):
app = FastAPI()
app.include_router(
get_reset_password_router(get_user_manager)
)
assert app.url_path_for("reset:forgot_password") == "/forgot-password"
@pytest.mark.asyncio
async def test_reset_password_namespace(
get_user_manager
):
app = FastAPI()
app.include_router(
get_reset_password_router(get_user_manager)
)
assert app.url_path_for("reset:reset_password") == "/reset-password"

View File

@ -98,6 +98,12 @@ class TestMe:
assert data["id"] == str(verified_user.id)
assert data["email"] == verified_user.email
async def test_current_user_namespace(
self,
app_factory
):
assert app_factory(True).url_path_for("users:current_user") == "/me"
@pytest.mark.router
@pytest.mark.asyncio
@ -465,6 +471,13 @@ class TestGetUser:
assert data["id"] == str(user.id)
assert "hashed_password" not in data
async def test_get_user_namespace(
self,
app_factory,
user: UserDB
):
assert app_factory(True).url_path_for("users:user", id=user.id) == f"/{user.id}"
@pytest.mark.router
@pytest.mark.asyncio

View File

@ -104,6 +104,19 @@ class TestVerifyTokenRequest:
response = await test_app_client.post("/request-verify-token", json=json)
assert response.status_code == status.HTTP_202_ACCEPTED
async def test_token_namespace(
self,
get_user_manager,
):
verify_router = get_verify_router(
get_user_manager,
User,
)
app = FastAPI()
app.include_router(verify_router)
assert app.url_path_for("verify:request-token") == "/request-verify-token"
@pytest.mark.router
@pytest.mark.asyncio
@ -166,3 +179,16 @@ class TestVerify:
assert response.status_code == status.HTTP_200_OK
data = cast(Dict[str, Any], response.json())
assert data["id"] == str(user.id)
async def test_verify_namespace(
self,
get_user_manager,
):
verify_router = get_verify_router(
get_user_manager,
User,
)
app = FastAPI()
app.include_router(verify_router)
assert app.url_path_for("verify:verify") == "/verify"