More highscore endpoint functionality & tests

This commit is contained in:
lvrossem 2023-04-12 12:02:25 -06:00
parent 73ce1bf2e0
commit f9aad400e0
3 changed files with 117 additions and 23 deletions

View File

@ -7,19 +7,40 @@ from src.models import HighScore, User
from src.schemas.highscores import HighScoreBase
from src.schemas.users import UserHighScore
DEFAULT_NR_HIGH_SCORES = 10
def get_high_scores(db: Session, minigame: MinigameEnum, nr_highest: int):
def get_high_scores(
db: Session, minigame: MinigameEnum, user: User, nr_highest: int, mine_only: bool
):
"""Get the n highest scores of a given minigame"""
if nr_highest:
if nr_highest < 1:
raise HTTPException(status_code=400, detail="Invalid number of high scores")
user_high_scores = []
if mine_only:
if nr_highest > 1:
raise HTTPException(
status_code=400,
detail="nr_highest should be 1 when requesting high score of current user only",
)
else:
high_score = (
db.query(HighScore)
.filter(
HighScore.minigame == minigame, HighScore.owner_id == user.user_id
)
.first()
)
if high_score:
return [
UserHighScore(
username=user.username,
score_value=high_score.score_value,
avatar=user.avatar,
)
]
else:
return []
if not nr_highest:
nr_highest = DEFAULT_NR_HIGH_SCORES
user_high_scores = []
if not minigame:
minigame = MinigameEnum.SpellingBee

View File

@ -64,11 +64,15 @@ async def login(user: users.UserCreate, db: Session = Depends(get_db)):
@app.get("/highscores/{minigame}", response_model=List[users.UserHighScore])
async def get_high_scores(
minigame: MinigameEnum,
nr_highest: Optional[int] = None,
nr_highest: Optional[int] = 1,
mine_only: Optional[bool] = True,
current_user_name: str = Depends(crud_authentication.get_current_user_name),
db: Session = Depends(get_db),
):
return crud_highscores.get_high_scores(db, minigame, nr_highest)
print(str(nr_highest))
print(str(mine_only))
user = crud_users.get_user_by_username(db, current_user_name)
return crud_highscores.get_high_scores(db, minigame, user, nr_highest, mine_only)
@app.put("/highscores/{minigame}", response_model=highscores.HighScore)
@ -107,13 +111,3 @@ async def patch_course_progress(
return crud_courseprogress.patch_course_progress(
db, current_user, course, course_progress
)
#### TESTING!! DELETE LATER
@app.get("/protected")
async def protected_route(
current_user_name: str = Depends(crud_authentication.get_current_user_name),
):
return {"message": f"Hello, {current_user_name}!"}

View File

@ -134,6 +134,13 @@ async def test_get_highscores_without_auth_should_fail():
assert response.status_code == 403
response = client.get(
f"/highscores/{minigame}?mine_only=false&nr_highest={random.randint(1, 50)}",
headers=headers,
)
assert response.status_code == 403
@pytest.mark.asyncio
async def test_get_highscore_for_nonexisting_minigame_should_fail():
@ -152,6 +159,13 @@ async def test_get_highscore_for_nonexisting_minigame_should_fail():
assert response.status_code == 422
response = client.get(
f"/highscores/{fake_minigame}?mine_only=false&nr_highest={random.randint(1, 50)}",
headers=headers,
)
assert response.status_code == 422
@pytest.mark.asyncio
async def test_get_invalid_number_of_highscores_should_fail():
@ -189,6 +203,7 @@ async def test_get_highscores_should_work_with_default_value():
@pytest.mark.asyncio
async def test_get_highscores_returns_sorted_list_with_correct_length():
"""Test whether getting a list of high scores gets a list in descending order and of the correct length"""
clear_db()
token = await register_user()
@ -197,6 +212,7 @@ async def test_get_highscores_returns_sorted_list_with_correct_length():
for minigame in MinigameEnum:
clear_db()
nr_entries = random.randint(5, 50)
token = ""
users_score_tuples = [
(f"user{i + 1}", random.random()) for i in range(nr_entries)
@ -214,7 +230,7 @@ async def test_get_highscores_returns_sorted_list_with_correct_length():
token = response.json()["access_token"]
response = client.put(
f"/highscores/{minigame}?nr_highest={random.randint(1, nr_entries)}",
f"/highscores/{minigame}",
headers={
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
@ -225,7 +241,7 @@ async def test_get_highscores_returns_sorted_list_with_correct_length():
assert response.status_code == 200
response = client.get(
f"/highscores/{minigame}",
f"/highscores/{minigame}?mine_only=false&nr_highest={int(nr_entries)}",
headers={
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
@ -235,5 +251,68 @@ async def test_get_highscores_returns_sorted_list_with_correct_length():
assert response.status_code == 200
response = response.json()
assert len(response) == nr_entries
for i in range(1, len(response)):
assert response[i]["score_value"] <= response[i - 1]["score_value"]
@pytest.mark.asyncio
async def test_get_own_existing_high_score_should_return_high_score():
"""Test whether fetching your own high score of a game succeeds"""
clear_db()
token = await register_user()
headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"}
for minigame in MinigameEnum:
response = client.put(
f"/highscores/{minigame}",
headers=headers,
json={"score_value": random.random()},
)
assert response.status_code == 200
response = client.get(
f"/highscores/{minigame}",
headers=headers,
)
assert response.status_code == 200
assert len(response.json()) == 1
@pytest.mark.asyncio
async def test_get_own_nonexisting_high_score_should_return_empty_list():
"""Test whether fetching the high score of a game you haven't played returns an empty list"""
clear_db()
token = await register_user()
headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"}
for minigame in MinigameEnum:
response = client.get(
f"/highscores/{minigame}",
headers=headers,
)
assert response.status_code == 200
assert len(response.json()) == 0
@pytest.mark.asyncio
async def test_get_multiple_own_high_scores_of_same_game_should_fail():
"""Test whether asking more than one of your high scores on a single game fails"""
clear_db()
token = await register_user()
headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"}
for minigame in MinigameEnum:
response = client.get(
f"/highscores/{minigame}?nr_highest={random.randint(2, 20)}",
headers=headers,
)
assert response.status_code == 400