diff --git a/gs/backend/api/v1/aro/endpoints/user.py b/gs/backend/api/v1/aro/endpoints/user.py index be8400978..f2e07b536 100644 --- a/gs/backend/api/v1/aro/endpoints/user.py +++ b/gs/backend/api/v1/aro/endpoints/user.py @@ -1,3 +1,68 @@ -from fastapi import APIRouter +from fastapi import APIRouter, HTTPException, status + +from gs.backend.api.v1.aro.models.requests import ChangeUserInfo, CreateUser, GetUserData +from gs.backend.data.data_wrappers.aro_wrapper.aro_user_data_wrapper import add_user, get_user_by_id, modify_user +from gs.backend.data.tables.aro_user_tables import AROUsers aro_user_router = APIRouter(tags=["ARO", "User Information"]) + + +@aro_user_router.post("/create_user/", status_code=status.HTTP_200_OK) +def create_user(payload: CreateUser) -> dict[str, AROUsers]: + """ + :param payload: Payload of type CreateUser, contains first_name, last_name, + call_sign, email, phone numer + all of type str + """ + try: + user = add_user( + call_sign=payload.call_sign, + email=payload.email, + f_name=payload.first_name, + l_name=payload.last_name, + phone_number=payload.phone_number, + ) + except ValueError as e: + raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=f"Invalid input: {e}") from e + + return {"user": user} + + +@aro_user_router.get("/get_user/", status_code=status.HTTP_200_OK) +def get_user(payload: GetUserData) -> dict[str, AROUsers]: + """ + :param payload: Payload of type GetUserData, contains user_id of type str + """ + try: + user_id = payload.user_id + + except KeyError as e: + raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail="Missing user_id") from e + try: + user = get_user_by_id(user_id) + return {"user": user} + + except ValueError as e: + raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"User does not exist, {e}") from e + + +@aro_user_router.put("/modify_user/", status_code=status.HTTP_200_OK) +def change_user_info(payload: ChangeUserInfo) -> dict[str, AROUsers]: + """ + :params payload: Payload of type ChangeUserInfo, contains user_id of type UUID, first_name, + last_name, call_sign + """ + try: + user_id = payload.user_id + + except KeyError as e: + raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail="Missing user_id") from e + + allowed_fields = {"first_name", "last_name", "call_sign"} + update_fields = {k: v for k, v in payload.model_dump().items() if v is not None and k in allowed_fields} + + try: + return {"data": modify_user(userid=user_id, **update_fields)} + + except ValueError as e: + raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e)) from e diff --git a/gs/backend/api/v1/aro/models/requests.py b/gs/backend/api/v1/aro/models/requests.py index e69de29bb..0ae3bfc26 100644 --- a/gs/backend/api/v1/aro/models/requests.py +++ b/gs/backend/api/v1/aro/models/requests.py @@ -0,0 +1,34 @@ +from uuid import UUID + +from pydantic import BaseModel + + +class CreateUser(BaseModel): + """ + Base model for create user, used for the create user endpoint + """ + + first_name: str + last_name: str + call_sign: str + email: str + phone_number: str + + +class ChangeUserInfo(BaseModel): + """ + Base model for changing user info, used for the change user info endpoint + """ + + user_id: UUID + first_name: str | None = None + last_name: str | None = None + call_sign: str | None = None + + +class GetUserData(BaseModel): + """ + Base model for getting user info, used by the get user info endpoint + """ + + user_id: UUID diff --git a/gs/backend/data/data_wrappers/aro_wrapper/aro_user_data_wrapper.py b/gs/backend/data/data_wrappers/aro_wrapper/aro_user_data_wrapper.py index fbb7aa89a..4c6396143 100644 --- a/gs/backend/data/data_wrappers/aro_wrapper/aro_user_data_wrapper.py +++ b/gs/backend/data/data_wrappers/aro_wrapper/aro_user_data_wrapper.py @@ -1,3 +1,4 @@ +from typing import Any from uuid import UUID from sqlmodel import select @@ -62,3 +63,38 @@ def delete_user_by_id(userid: UUID) -> list[AROUsers]: raise ValueError("User ID does not exist") return get_all_users() + + +# gets the user with given id +def get_user_by_id(userid: UUID) -> AROUsers: + """ + Use the user.id to delete a user from table + + :param userid: identifier unique to the user + """ + with get_db_session() as session: + user = session.get(AROUsers, userid) + + if user: + return user + else: + raise ValueError("User ID does not exist") + + +def modify_user(userid: UUID, **kwargs: dict[str, Any]) -> AROUsers: + """ + Modifies the target user + + :param userid: identifier unique to the user + """ + with get_db_session() as session: + user = session.get(AROUsers, userid) + if not user: + raise ValueError("User does not exist based on ID") + + for field, value in kwargs.items(): + setattr(user, field, value) + + session.commit() + session.refresh(user) + return user diff --git a/python_test/test_user_api_endpoint.py b/python_test/test_user_api_endpoint.py new file mode 100644 index 000000000..ef4e98d17 --- /dev/null +++ b/python_test/test_user_api_endpoint.py @@ -0,0 +1,22 @@ +from fastapi.testclient import TestClient +from gs.backend.main import app + + +def test_create_user(): + with TestClient(app) as client: + json_obj = { + "call_sign": "KEVWAN", + "email": "kevwan19@gmail.com", + "first_name": "kevin", + "last_name": "wan", + "phone_number": "18008888888", + } + + res = client.post("/api/v1/aro/user/create_user/", json=json_obj) + assert res.status_code == 200 + user = res.model_dump().get("user") + assert user.call_sign == "KEVWAN" + assert user.email == "kevwan19@gmail.com" + assert user.first_name == "kevin" + assert user.last_name == "wan" + assert user.phone_number == "18008888888"