From 4235395579edd9999ef8161fd012912e7a705aea Mon Sep 17 00:00:00 2001 From: lvrossem Date: Tue, 18 Apr 2023 05:24:17 -0600 Subject: [PATCH] Finish up learnable tests --- src/crud/learnableprogress.py | 15 +- src/main.py | 5 +- tests/test_learnables.py | 261 ++++++++++++++++++++++++++++++++++ tests/test_users.py | 2 +- 4 files changed, 278 insertions(+), 5 deletions(-) diff --git a/src/crud/learnableprogress.py b/src/crud/learnableprogress.py index 2d7a31f..5ab0de1 100644 --- a/src/crud/learnableprogress.py +++ b/src/crud/learnableprogress.py @@ -77,11 +77,11 @@ def create_learnable( db.commit() -def patch_learnable(db: Session, user: User, learnable: SavedLearnableProgress): +def patch_learnable(db: Session, user: User, learnable_name: str, learnable: SavedLearnableProgress): """Patch an existing learnable""" db_learnable = ( db.query(LearnableProgress) - .filter(LearnableProgress.name == learnable.name) + .filter(LearnableProgress.name == learnable_name) .first() ) @@ -90,6 +90,17 @@ def patch_learnable(db: Session, user: User, learnable: SavedLearnableProgress): status_code=400, detail="Learnable with provided name not found" ) + potential_duplicate = ( + db.query(LearnableProgress) + .filter(LearnableProgress.name == learnable.name, LearnableProgress.learnable_progress_id != db_learnable.learnable_progress_id) + .first() + ) + + if potential_duplicate: + raise HTTPException( + status_code=400, detail="No duplicate learnable names allowed" + ) + if learnable.index < -1: raise HTTPException(status_code=400, detail="Invalid learnable index") elif learnable.index > -1: diff --git a/src/main.py b/src/main.py index c9f2cc2..5a405c2 100644 --- a/src/main.py +++ b/src/main.py @@ -152,11 +152,12 @@ async def create_learnable( crud_learnables.create_learnable(db, current_user, course, learnable) -@app.patch("/learnables") +@app.patch("/learnables/{name}") async def create_learnable( + name: str, 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) + crud_learnables.patch_learnable(db, current_user, name, learnable) diff --git a/tests/test_learnables.py b/tests/test_learnables.py index 1c2d03b..b7c318e 100644 --- a/tests/test_learnables.py +++ b/tests/test_learnables.py @@ -9,6 +9,7 @@ from tests.config.database import clear_db @pytest.mark.asyncio async def test_create_learnables_should_succeed(): + """Test whether creating a new learnable succeeds""" clear_db() token = await register_user() @@ -37,3 +38,263 @@ async def test_create_learnables_should_succeed(): response = response.json() assert len(response) == nr_learnables +@pytest.mark.asyncio +async def test_patch_learnables_should_succeed(): + """Test whether patching learnables succeeds""" + clear_db() + token = await register_user() + + headers = get_headers(token) + + for course in CourseEnum: + if course != CourseEnum.All: + + response = client.post( + f"/learnables/{course}", + json={ + "index": random.randint(0, 100), + "in_use": bool(random.randint(0, 1)), + "name": f"{course}", + }, + headers=headers, + ) + + assert response.status_code == 200 + + new_index = random.randint(0, 100) + new_in_use = bool(random.randint(0, 1)) + new_name = "New" + course + + response = client.patch(f"/learnables/{course}", json={"index": new_index, "in_use": new_in_use, "name": new_name}, headers=headers) + + assert response.status_code == 200 + + response = client.get(f"/learnables/{course}", headers=headers) + + assert response.status_code == 200 + + response = response.json()[0] + + assert response["index"] == new_index + assert response["in_use"] == new_in_use + assert response["name"] == new_name + + + +@pytest.mark.asyncio +async def test_create_learnables_without_name_should_fail(): + """Test whether creating a new learnable without name fails""" + clear_db() + token = await register_user() + + headers = get_headers(token) + + for course in CourseEnum: + if course != CourseEnum.All: + response = client.post( + f"/learnables/{course}", + json={ + "index": random.randint(0, 100), + "in_use": bool(random.randint(0, 1)), + }, + headers=headers, + ) + + assert response.status_code == 400 + + +@pytest.mark.asyncio +async def test_create_learnables_without_index_should_fail(): + """Test whether creating a new learnable without index fails""" + clear_db() + token = await register_user() + + headers = get_headers(token) + + for course in CourseEnum: + if course != CourseEnum.All: + response = client.post( + f"/learnables/{course}", + json={ + "name": course, + "in_use": bool(random.randint(0, 1)), + }, + headers=headers, + ) + + assert response.status_code == 400 + + +@pytest.mark.asyncio +async def test_create_learnables_without_in_use_should_fail(): + """Test whether creating a new learnable without in_use fails""" + clear_db() + token = await register_user() + + headers = get_headers(token) + + for course in CourseEnum: + if course != CourseEnum.All: + response = client.post( + f"/learnables/{course}", + json={ + "index": random.randint(0, 100), + "name": course, + }, + headers=headers, + ) + + assert response.status_code == 400 + + +@pytest.mark.asyncio +async def test_create_learnable_without_auth_should_fail(): + """Test whether creating learnables without authentication fails""" + clear_db() + + for course in CourseEnum: + if course != CourseEnum.All: + response = client.post( + f"/learnables/{course}", + json={ + "index": 0, + "in_use": bool(random.randint(0, 1)), + "name": f"{course}", + }, + headers=get_headers(), + ) + + assert response.status_code == 403 + + +@pytest.mark.asyncio +async def test_get_learnables_of_nonexisting_course_should_fail(): + """Test whether learnables of a nonexisting course fails""" + clear_db() + token = await register_user() + + course = "FakeCourse" + + response = client.get(f"/learnables/{course}", headers=get_headers(token)) + + assert response.status_code == 422 + + +@pytest.mark.asyncio +async def test_post_learnable_to_nonexisting_course_should_fail(): + """Test whether creating a learnable for a nonexisting course fails fails""" + clear_db() + token = await register_user() + + course = "FakeCourse" + + response = client.post( + f"/learnables/{course}", + json={ + "index": 0, + "in_use": bool(random.randint(0, 1)), + "name": f"{course}", + }, + headers=get_headers(token), + ) + + assert response.status_code == 422 + + +@pytest.mark.asyncio +async def test_get_learnables_without_auth_should_fail(): + """Test whether fetching learnables without authentication fails""" + clear_db() + + for course in CourseEnum: + if course != CourseEnum.All: + response = client.get(f"/learnables/{course}", headers=get_headers()) + + assert response.status_code == 403 + + +@pytest.mark.asyncio +async def test_patch_learnable_without_auth_should_fail(): + """Test whether patching learnables without authentication fails""" + clear_db() + token = await register_user() + + for course in CourseEnum: + if course != CourseEnum.All: + response = client.post( + f"/learnables/{course}", + json={ + "index": 0, + "in_use": bool(random.randint(0, 1)), + "name": f"{course}", + }, + headers=get_headers(token), + ) + + assert response.status_code == 200 + + response = client.patch( + f"/learnables/{course}", + json={ + "index": 0, + "in_use": bool(random.randint(0, 1)), + "name": f"{course}", + }, + headers=get_headers(), + ) + + assert response.status_code == 403 + + +@pytest.mark.asyncio +async def test_create_learnable_with_existing_name_should_fail(): + """Test whether putting high scores without authentication fails""" + clear_db() + token = await register_user() + + for course in CourseEnum: + if course != CourseEnum.All: + response = client.post( + f"/learnables/{course}", + json={ + "index": 0, + "in_use": bool(random.randint(0, 1)), + "name": f"{course}", + }, + headers=get_headers(token), + ) + + assert response.status_code == 200 + + response = client.post( + f"/learnables/{course}", + json={ + "index": 1, + "in_use": bool(random.randint(0, 1)), + "name": f"{course}", + }, + headers=get_headers(token), + ) + + assert response.status_code == 400 + + +@pytest.mark.asyncio +async def test_patch_nonexisting_learnable_should_fail(): + """Test whether patching nonexisting learnables fails""" + clear_db() + token = await register_user() + + for course in CourseEnum: + if course != CourseEnum.All: + response = client.patch( + f"/learnables/{course}", + json={ + "index": 0, + "in_use": bool(random.randint(0, 1)), + "name": f"{course}", + }, + headers=get_headers(token), + ) + + assert response.status_code == 400 diff --git a/tests/test_users.py b/tests/test_users.py index 037ff98..bfd3a72 100644 --- a/tests/test_users.py +++ b/tests/test_users.py @@ -1,6 +1,6 @@ import pytest -from tests.base import (avatar_index, client, get_headers, register_user, +from tests.base import (client, get_headers, register_user, username) from tests.config.database import clear_db