Finish off backend tests

This commit is contained in:
lvrossem
2023-04-10 16:07:25 -06:00
parent 8e128ca033
commit 73ce1bf2e0
9 changed files with 285 additions and 72 deletions

View File

@@ -1,5 +1,5 @@
from sqlalchemy.orm import Session
from fastapi import HTTPException from fastapi import HTTPException
from sqlalchemy.orm import Session
from src.enums import CourseEnum from src.enums import CourseEnum
from src.models import CourseProgress, User from src.models import CourseProgress, User
@@ -50,7 +50,9 @@ def initialize_user(db: Session, user: User):
db.commit() db.commit()
def patch_course_progress(db: Session, user: User, course: CourseEnum, course_progress: CourseProgressBase): def patch_course_progress(
db: Session, user: User, course: CourseEnum, course_progress: CourseProgressBase
):
"""Change the progress value for a given course""" """Change the progress value for a given course"""
if course_progress.progress_value > 1 or course_progress.progress_value < 0: if course_progress.progress_value > 1 or course_progress.progress_value < 0:
raise HTTPException(status_code=400, detail="Invalid progress value") raise HTTPException(status_code=400, detail="Invalid progress value")

View File

@@ -12,8 +12,9 @@ DEFAULT_NR_HIGH_SCORES = 10
def get_high_scores(db: Session, minigame: MinigameEnum, nr_highest: int): def get_high_scores(db: Session, minigame: MinigameEnum, nr_highest: int):
"""Get the n highest scores of a given minigame""" """Get the n highest scores of a given minigame"""
if nr_highest < 1: if nr_highest:
raise HTTPException(status_code=400, detail="Invalid number of high scores") if nr_highest < 1:
raise HTTPException(status_code=400, detail="Invalid number of high scores")
user_high_scores = [] user_high_scores = []
@@ -42,7 +43,9 @@ def get_high_scores(db: Session, minigame: MinigameEnum, nr_highest: int):
return user_high_scores return user_high_scores
def create_high_score(db: Session, user: User, minigame: MinigameEnum, high_score: HighScoreBase): def create_high_score(
db: Session, user: User, minigame: MinigameEnum, high_score: HighScoreBase
):
"""Create a new high score for a given minigame""" """Create a new high score for a given minigame"""
def add_to_db(): def add_to_db():

View File

@@ -65,16 +65,17 @@ async def login(user: users.UserCreate, db: Session = Depends(get_db)):
async def get_high_scores( async def get_high_scores(
minigame: MinigameEnum, minigame: MinigameEnum,
nr_highest: Optional[int] = None, nr_highest: Optional[int] = None,
current_user_name: str = Depends(crud_authentication.get_current_user_name),
db: Session = Depends(get_db), db: Session = Depends(get_db),
): ):
return crud_highscores.get_high_scores(db, minigame, nr_highest) return crud_highscores.get_high_scores(db, minigame, nr_highest)
@app.post("/highscores/{minigame}", response_model=highscores.HighScore) @app.put("/highscores/{minigame}", response_model=highscores.HighScore)
async def create_high_score( async def create_high_score(
minigame: MinigameEnum, minigame: MinigameEnum,
high_score: highscores.HighScoreBase, high_score: highscores.HighScoreBase,
current_user_name=Depends(crud_authentication.get_current_user_name), current_user_name: str = Depends(crud_authentication.get_current_user_name),
db: Session = Depends(get_db), db: Session = Depends(get_db),
): ):
current_user = crud_users.get_user_by_username(db, current_user_name) current_user = crud_users.get_user_by_username(db, current_user_name)
@@ -93,7 +94,9 @@ async def get_course_progress(
return crud_courseprogress.get_course_progress(db, current_user, course) return crud_courseprogress.get_course_progress(db, current_user, course)
@app.patch("/courseprogress/{course}", response_model=List[courseprogress.CourseProgressParent]) @app.patch(
"/courseprogress/{course}", response_model=List[courseprogress.CourseProgressParent]
)
async def patch_course_progress( async def patch_course_progress(
course: CourseEnum, course: CourseEnum,
course_progress: courseprogress.CourseProgressBase, course_progress: courseprogress.CourseProgressBase,
@@ -101,7 +104,9 @@ async def patch_course_progress(
db: Session = Depends(get_db), db: Session = Depends(get_db),
): ):
current_user = crud_users.get_user_by_username(db, current_user_name) current_user = crud_users.get_user_by_username(db, current_user_name)
return crud_courseprogress.patch_course_progress(db, current_user, course, course_progress) return crud_courseprogress.patch_course_progress(
db, current_user, course, course_progress
)
#### TESTING!! DELETE LATER #### TESTING!! DELETE LATER

16
tests/base.py Normal file
View File

@@ -0,0 +1,16 @@
import sys
from fastapi.testclient import TestClient
sys.path.append("..")
from src.main import app, get_db
from tests.config.database import override_get_db
app.dependency_overrides[get_db] = override_get_db
client = TestClient(app)
username = "user1"
password = "password"
avatar = "lion"

View File

@@ -1,21 +1,10 @@
import sys
import pytest import pytest
from fastapi.testclient import TestClient from fastapi.testclient import TestClient
sys.path.append("..")
from src.main import app, get_db from src.main import app, get_db
from tests.base import avatar, client, password, username
from tests.config.database import clear_db, override_get_db from tests.config.database import clear_db, override_get_db
app.dependency_overrides[get_db] = override_get_db
client = TestClient(app)
username = "user1"
password = "password"
avatar = "lion"
async def register_user(): async def register_user():
response = client.post( response = client.post(

View File

@@ -1,23 +1,13 @@
import random import random
import sys
import pytest import pytest
from fastapi.testclient import TestClient from fastapi.testclient import TestClient
sys.path.append("..")
from src.enums import CourseEnum from src.enums import CourseEnum
from src.main import app, get_db from src.main import app, get_db
from tests.base import avatar, client, password, username
from tests.config.database import clear_db, override_get_db from tests.config.database import clear_db, override_get_db
app.dependency_overrides[get_db] = override_get_db
client = TestClient(app)
username = "user1"
password = "password"
avatar = "lion"
async def register_user(): async def register_user():
response = client.post( response = client.post(
@@ -67,6 +57,19 @@ async def test_get_all_returns_all():
assert {"progress_value": 0.0, "course": course} in response assert {"progress_value": 0.0, "course": course} in response
@pytest.mark.asyncio
async def test_get_course_progress_value_without_auth_should_fail():
"""Test whether fetching a course progress value without authentication fails"""
clear_db()
headers = {"Content-Type": "application/json"}
for course in CourseEnum:
response = client.get(f"/courseprogress/{course}", headers=headers)
assert response.status_code == 403
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_get_nonexisting_course_should_fail(): async def test_get_nonexisting_course_should_fail():
"""Test whether fetching the progress of a nonexisting course fails""" """Test whether fetching the progress of a nonexisting course fails"""
@@ -178,3 +181,20 @@ async def test_patch_course_with_invalid_value_should_fail():
) )
assert response.status_code == 400 assert response.status_code == 400
@pytest.mark.asyncio
async def test_patch_course_progress_value_without_auth_should_fail():
"""Test whether updating a course progress value without authentication fails"""
clear_db()
headers = {"Content-Type": "application/json"}
for course in CourseEnum:
response = client.patch(
f"/courseprogress/{course}",
headers=headers,
json={"progress_value": random.uniform(0, 1)},
)
assert response.status_code == 403

View File

@@ -1,21 +1,13 @@
import sys import random
import pytest import pytest
from fastapi.testclient import TestClient from fastapi.testclient import TestClient
sys.path.append("..") from src.enums import MinigameEnum
from src.main import app, get_db from src.main import app, get_db
from tests.base import avatar, client, password, username
from tests.config.database import clear_db, override_get_db from tests.config.database import clear_db, override_get_db
app.dependency_overrides[get_db] = override_get_db
client = TestClient(app)
username = "user1"
password = "password"
avatar = "lion"
async def register_user(): async def register_user():
response = client.post( response = client.post(
@@ -30,6 +22,218 @@ async def register_user():
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_post_highscore(): async def test_put_highscore():
"""Test whether posting a new high score succeeds""" """Test whether putting a new high score succeeds"""
clear_db() clear_db()
token = await register_user()
headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"}
for minigame in MinigameEnum:
score_value = random.random()
response = client.put(
f"/highscores/{minigame}",
headers=headers,
json={"score_value": score_value},
)
assert response.status_code == 200
response = response.json()
assert response["minigame"] == minigame
assert response["score_value"] == score_value
@pytest.mark.asyncio
async def test_put_lower_highscore_does_not_change_old_value():
"""Test whether putting a new high score lower than the current one doesn't change the old one"""
clear_db()
token = await register_user()
headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"}
for minigame in MinigameEnum:
score_value = random.random()
response = client.put(
f"/highscores/{minigame}",
headers=headers,
json={"score_value": score_value},
)
assert response.status_code == 200
response = response.json()
assert response["minigame"] == minigame
assert response["score_value"] == score_value
lower_score_value = score_value - 100
response = client.put(
f"/highscores/{minigame}",
headers=headers,
json={"score_value": lower_score_value},
)
assert response.status_code == 200
response = response.json()
assert response["minigame"] == minigame
assert response["score_value"] == score_value
@pytest.mark.asyncio
async def test_put_highscore_for_nonexisting_minigame_should_fail():
"""Test whether putting a new high score for a nonexisting minigame fails"""
clear_db()
token = await register_user()
fake_minigame = "FakeGame"
headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"}
response = client.put(
f"/highscores/{fake_minigame}",
headers=headers,
json={"score_value": random.random()},
)
assert response.status_code == 422
@pytest.mark.asyncio
async def test_put_highscores_without_auth_should_fail():
"""Test whether putting high scores without authentication fails"""
clear_db()
headers = {"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 == 403
@pytest.mark.asyncio
async def test_get_highscores_without_auth_should_fail():
"""Test whether fetching high scores without authentication fails"""
clear_db()
headers = {"Content-Type": "application/json"}
for minigame in MinigameEnum:
response = client.get(
f"/highscores/{minigame}",
headers=headers,
)
assert response.status_code == 403
@pytest.mark.asyncio
async def test_get_highscore_for_nonexisting_minigame_should_fail():
"""Test whether fetching a new high score for a nonexisting minigame fails"""
clear_db()
token = await register_user()
fake_minigame = "FakeGame"
headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"}
response = client.get(
f"/highscores/{fake_minigame}",
headers=headers,
)
assert response.status_code == 422
@pytest.mark.asyncio
async def test_get_invalid_number_of_highscores_should_fail():
"""Test whether getting a numbe rof high scores lower than 1 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(-100, 0)}",
headers=headers,
)
assert response.status_code == 400
@pytest.mark.asyncio
async def test_get_highscores_should_work_with_default_value():
"""Test whether fetching high scores without passing an explicit amount still succeeds"""
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
@pytest.mark.asyncio
async def test_get_highscores_returns_sorted_list_with_correct_length():
clear_db()
token = await register_user()
headers = {"Content-Type": "application/json"}
for minigame in MinigameEnum:
clear_db()
nr_entries = random.randint(5, 50)
users_score_tuples = [
(f"user{i + 1}", random.random()) for i in range(nr_entries)
]
for user, score in users_score_tuples:
response = client.post(
"/register",
headers=headers,
json={"username": user, "password": password, "avatar": avatar},
)
assert response.status_code == 200
token = response.json()["access_token"]
response = client.put(
f"/highscores/{minigame}?nr_highest={random.randint(1, nr_entries)}",
headers={
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
},
json={"score_value": score},
)
assert response.status_code == 200
response = client.get(
f"/highscores/{minigame}",
headers={
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
},
)
assert response.status_code == 200
response = response.json()
for i in range(1, len(response)):
assert response[i]["score_value"] <= response[i - 1]["score_value"]

View File

@@ -1,21 +1,10 @@
import sys
import pytest import pytest
from fastapi.testclient import TestClient from fastapi.testclient import TestClient
sys.path.append("..")
from src.main import app, get_db from src.main import app, get_db
from tests.base import avatar, client, password, username
from tests.config.database import clear_db, override_get_db from tests.config.database import clear_db, override_get_db
app.dependency_overrides[get_db] = override_get_db
client = TestClient(app)
username = "user1"
password = "password"
avatar = "lion"
patched_username = "New name" patched_username = "New name"
patched_password = "New password" patched_password = "New password"
patched_avatar = "New avatar" patched_avatar = "New avatar"

View File

@@ -1,15 +0,0 @@
import pytest
from fastapi.testclient import TestClient
from main import app
client = TestClient(app)
def test_add_user():
response = client.post(
"/users",
headers={"Content-Type": "application/json"},
json={"username": "Lukas", "password": "mettn"},
)
assert response.status_code == 200