More and more refactors

This commit is contained in:
lvrossem
2023-04-17 15:38:25 -06:00
parent 81e9eb154b
commit d074074b03
11 changed files with 139 additions and 42 deletions

View File

@@ -97,7 +97,9 @@ def create_high_score(
db.add(db_high_score) db.add(db_high_score)
db.commit() db.commit()
db.refresh(db_high_score) db.refresh(db_high_score)
return Score(score_value=db_high_score.score_value, time=str(db_high_score.time)) return Score(
score_value=db_high_score.score_value, time=str(db_high_score.time)
)
old_high_score = ( old_high_score = (
db.query(HighScore) db.query(HighScore)
@@ -112,6 +114,8 @@ def create_high_score(
db.delete(old_high_score) db.delete(old_high_score)
return add_to_db() return add_to_db()
else: else:
return Score(score_value=old_high_score.score_value, time=str(old_high_score.time)) return Score(
score_value=old_high_score.score_value, time=str(old_high_score.time)
)
else: else:
return add_to_db() return add_to_db()

View File

@@ -0,0 +1,84 @@
from fastapi import HTTPException
from sqlalchemy.orm import Session
from src.enums import CourseEnum
from src.models import CourseProgress, LearnableProgress, User
from src.schemas.learnableprogress import SavedLearnableProgress
def create_learnable(
db: Session, user: User, course: CourseEnum, learnable: SavedLearnableProgress
):
"""Create a new learnable"""
if learnable.index < 0:
raise HTTPException(status_code=400, detail="Negative index not allowed")
if learnable.in_use is None:
raise HTTPException(
status_code=400, detail="Please indicate whether the learnable is in use"
)
if len(learnable.name) < 1:
raise HTTPException(
status_code=400, detail="No name was provided for the learnable"
)
potential_duplicate = (
db.query(LearnableProgress)
.filter(LearnableProgress.name == learnable.name)
.first()
)
if potential_duplicate:
raise HTTPException(
status_code=400, detail="No duplicate learnable names allowed"
)
db_course = (
db.query(CourseProgress)
.filter(
CourseProgress.owner_id == user.user_id, CourseProgress.course == course
)
.first()
)
db_learnable = LearnableProgress(
index=learnable.index,
in_use=learnable.in_use,
name=learnable.name,
progress=0.0,
course_progress_id=db_course.course_progress_id,
)
db.add(db_learnable)
db.commit()
def patch_learnable(db: Session, user: User, learnable: SavedLearnableProgress):
"""Patch an existing learnable"""
db_learnable = (
db.query(LearnableProgress)
.filter(LearnableProgress.name == learnable.name)
.first()
)
if not db_learnable:
raise HTTPException(
status_code=400, detail="Learnable with provided name not found"
)
if learnable.index < -1:
raise HTTPException(status_code=400, detail="Invalid learnable index")
elif learnable.index > -1:
db_learnable.index = learnable.index
if learnable.in_use is not None:
db_learnable.in_use = learnable.in_use
if len(learnable.name) > 0:
db_learnable.name = learnable.name
# TODO: chek progress semantics
db.add(db_learnable)
db.commit()

View File

@@ -2,16 +2,14 @@ from fastapi import HTTPException
from passlib.context import CryptContext from passlib.context import CryptContext
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from src.models import User
from src.crud.highscores import (get_highest_high_scores, from src.crud.highscores import (get_highest_high_scores,
get_most_recent_high_scores) get_most_recent_high_scores)
from src.schemas.users import UserCreate
from src.enums import CourseEnum, MinigameEnum from src.enums import CourseEnum, MinigameEnum
from src.models import CourseProgress, LearnableProgress from src.models import CourseProgress, LearnableProgress, User
from src.schemas.highscores import SavedMinigameProgress
from src.schemas.courseprogress import SavedCourseProgress from src.schemas.courseprogress import SavedCourseProgress
from src.schemas.highscores import SavedMinigameProgress
from src.schemas.learnableprogress import SavedLearnableProgress from src.schemas.learnableprogress import SavedLearnableProgress
from src.schemas.users import SavedUser from src.schemas.users import SavedUser, UserCreate
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
@@ -28,7 +26,7 @@ def check_empty_fields(username: str, password: str, avatar_index: int):
def patch_user(db: Session, username: str, user: UserCreate): def patch_user(db: Session, username: str, user: UserCreate):
"""Changes the username and/or the password of a User""" """Changes the username and/or the password of a User"""
#check_empty_fields(user.username, user.password, user.avatar_index) # check_empty_fields(user.username, user.password, user.avatar_index)
db_user = get_user_by_username(db, username) db_user = get_user_by_username(db, username)
potential_duplicate = get_user_by_username(db, user.username) potential_duplicate = get_user_by_username(db, user.username)
if potential_duplicate: if potential_duplicate:
@@ -46,6 +44,8 @@ def patch_user(db: Session, username: str, user: UserCreate):
if user.avatar_index > -1: if user.avatar_index > -1:
db_user.avatar_index = user.avatar_index db_user.avatar_index = user.avatar_index
elif user.avatar_index < -1:
raise HTTPException(status_code=400, detail="Invalid avatar index")
db_user.playtime += user.playtime db_user.playtime += user.playtime
db.commit() db.commit()

View File

@@ -2,24 +2,6 @@ from fastapi_utils.enums import StrEnum
from sqlalchemy.types import Enum, TypeDecorator from sqlalchemy.types import Enum, TypeDecorator
class StrEnumType(TypeDecorator):
impl = Enum
def __init__(self, enum_class, **kw):
self.enum_class = enum_class
super().__init__(enum_class, **kw)
def process_bind_param(self, value, dialect):
if value is None:
return None
return value.value
def process_result_value(self, value, dialect):
if value is None:
return None
return self.enum_class(value)
class MinigameEnum(StrEnum): class MinigameEnum(StrEnum):
SpellingBee = "SpellingBee" SpellingBee = "SpellingBee"
Hangman = "Hangman" Hangman = "Hangman"

View File

@@ -9,10 +9,11 @@ sys.path.append("..")
from src.crud import authentication as crud_authentication from src.crud import authentication as crud_authentication
from src.crud import courseprogress as crud_courseprogress from src.crud import courseprogress as crud_courseprogress
from src.crud import highscores as crud_highscores from src.crud import highscores as crud_highscores
from src.crud import learnableprogress as crud_learnables
from src.crud import users as crud_users from src.crud import users as crud_users
from src.database import Base, engine, get_db from src.database import Base, engine, get_db
from src.enums import CourseEnum, MinigameEnum from src.enums import CourseEnum, MinigameEnum
from src.schemas import courseprogress, highscores, users from src.schemas import courseprogress, highscores, learnableprogress, users
app = FastAPI() app = FastAPI()
@@ -23,6 +24,7 @@ Base.metadata.create_all(bind=engine)
async def root(): async def root():
return {"message": "Hello world!"} return {"message": "Hello world!"}
""" """
@app.get("/allusers", response_model=List[users.SavedUser]) @app.get("/allusers", response_model=List[users.SavedUser])
async def read_users(db: Session = Depends(get_db)): async def read_users(db: Session = Depends(get_db)):
@@ -38,6 +40,7 @@ async def read_user(
return crud_users.get_user_by_username(db, current_user_name) return crud_users.get_user_by_username(db, current_user_name)
""" """
@app.patch("/users") @app.patch("/users")
async def patch_current_user( async def patch_current_user(
user: users.UserCreate, user: users.UserCreate,
@@ -123,3 +126,24 @@ async def patch_course_progress(
return crud_courseprogress.patch_course_progress( return crud_courseprogress.patch_course_progress(
db, current_user, course, course_progress db, current_user, course, course_progress
) )
@app.post("/learnables/{course}")
async def create_learnable(
course: CourseEnum,
learnable: learnableprogress.SavedLearnableProgress,
current_user_name: str = Depends(crud_authentication.get_current_user_name),
db: Session = Depends(get_db),
):
current_user = crud_users.get_user_by_username(db, current_user_name)
crud_learnables.create_learnable(db, current_user, course, learnable)
@app.patch("/learnables")
async def create_learnable(
learnable: learnableprogress.SavedLearnableProgress,
current_user_name: str = Depends(crud_authentication.get_current_user_name),
db: Session = Depends(get_db),
):
current_user = crud_users.get_user_by_username(db, current_user_name)
crud_learnables.patch_learnable(db, current_user, learnable)

View File

@@ -1,8 +1,9 @@
from typing import List
from pydantic import BaseModel from pydantic import BaseModel
from src.enums import CourseEnum from src.enums import CourseEnum
from src.schemas.learnableprogress import SavedLearnableProgress from src.schemas.learnableprogress import SavedLearnableProgress
from typing import List
class CourseProgressBase(BaseModel): class CourseProgressBase(BaseModel):

View File

@@ -1,8 +1,8 @@
from typing import List
from pydantic import BaseModel from pydantic import BaseModel
from src.enums import MinigameEnum from src.enums import MinigameEnum
from typing import List
class HighScoreBase(BaseModel): class HighScoreBase(BaseModel):

View File

@@ -1,7 +1,8 @@
from pydantic import BaseModel from pydantic import BaseModel
class SavedLearnableProgress(BaseModel): class SavedLearnableProgress(BaseModel):
index: int index: int = -1
in_use: bool in_use: bool = None
name: str name: str = ""
progress: float progress: float = -1.0

View File

@@ -1,7 +1,9 @@
from pydantic import BaseModel
from typing import List from typing import List
from src.schemas.highscores import SavedMinigameProgress
from pydantic import BaseModel
from src.schemas.courseprogress import SavedCourseProgress from src.schemas.courseprogress import SavedCourseProgress
from src.schemas.highscores import SavedMinigameProgress
class UserBase(BaseModel): class UserBase(BaseModel):

View File

@@ -3,7 +3,7 @@ import random
import pytest import pytest
from src.enums import MinigameEnum from src.enums import MinigameEnum
from tests.base import client, password, avatar_index, register_user from tests.base import avatar_index, client, password, register_user
from tests.config.database import clear_db from tests.config.database import clear_db

View File

@@ -8,7 +8,6 @@ patched_password = "New password"
patched_avatar_index = 2 patched_avatar_index = 2
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_patch_user(): async def test_patch_user():
"""Test the patching of a user's username, password and avatar""" """Test the patching of a user's username, password and avatar"""
@@ -62,7 +61,7 @@ async def test_patch_user_with_empty_fields():
"username": "", "username": "",
"password": patched_password, "password": patched_password,
"avatar_index": patched_avatar_index, "avatar_index": patched_avatar_index,
"playtime": 0.0 "playtime": 0.0,
}, },
headers=headers, headers=headers,
) )
@@ -74,7 +73,7 @@ async def test_patch_user_with_empty_fields():
"username": username, "username": username,
"password": patched_password, "password": patched_password,
"avatar_index": -1, "avatar_index": -1,
"playtime": 0.0 "playtime": 0.0,
}, },
headers=headers, headers=headers,
) )
@@ -86,7 +85,7 @@ async def test_patch_user_with_empty_fields():
"username": username, "username": username,
"password": "", "password": "",
"avatar_index": patched_avatar_index, "avatar_index": patched_avatar_index,
"playtime": 0.0 "playtime": 0.0,
}, },
headers=headers, headers=headers,
) )