New files
storeapi/routers/user.py
import logging
from fastapi import APIRouter, HTTPException, status
from storeapi.database import database, user_table
from storeapi.models.user import UserIn
from storeapi.security import get_user
logger = logging.getLogger(__name__)
router = APIRouter()
@router.post("/register", status_code=201)
async def register(user: UserIn):
if await get_user(user.email):
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="A user with that email already exists",
)
# This is a VERY BAD idea! You should never store passwords in plain text!
query = user_table.insert().values(email=user.email, password=user.password)
logger.debug(query)
await database.execute(query)
return {"detail": "User created."}
storeapi/tests/test_security.py
import pytest
from storeapi import security
@pytest.mark.anyio
async def test_get_user(registered_user: dict):
user = await security.get_user(registered_user["email"])
assert user.email == registered_user["email"]
@pytest.mark.anyio
async def test_get_user_not_found():
user = await security.get_user("test@example.com")
assert user is None
storeapi/models/user.py
from pydantic import BaseModel
class User(BaseModel):
id: int | None = None
email: str
class UserIn(User):
password: str
Modified files
storeapi/main.py
---
+++
@@ -7,6 +7,7 @@
from storeapi.database import database
from storeapi.logging_conf import configure_logging
from storeapi.routers.post import router as post_router
+from storeapi.routers.user import router as user_router
logger = logging.getLogger(__name__)
@@ -19,8 +20,7 @@
app = FastAPI(lifespan=lifespan)
app.add_middleware(CorrelationIdMiddleware)
-
-
+app.include_router(user_router)
app.include_router(post_router)
storeapi/tests/conftest.py
---
+++
@@ -6,7 +6,7 @@
from httpx import AsyncClient
os.environ["ENV_STATE"] = "test"
-from storeapi.database import database # noqa: E402
+from storeapi.database import database, user_table # noqa: E402
from storeapi.main import app # noqa: E402
@@ -31,3 +31,13 @@
async def async_client(client) -> AsyncGenerator:
async with AsyncClient(app=app, base_url=client.base_url) as ac:
yield ac
+
+
+@pytest.fixture()
+async def registered_user(async_client: AsyncClient):
+ user_details = {"email": "test@example.net", "password": "1234"}
+ await async_client.post("/register", json=user_details)
+ query = user_table.select().where(user_table.c.email == user_details["email"])
+ user = await database.fetch_one(query)
+ user_details["id"] = user.id
+ return user_details