import random import pytest from fastapi.testclient import TestClient from src.enums import CourseEnum 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 async def register_user(): response = client.post( "/register", headers={"Content-Type": "application/json"}, json={"username": username, "password": password, "avatar": avatar}, ) assert response.status_code == 200 return response.json()["access_token"] @pytest.mark.asyncio async def test_register_creates_progress_of_zero(): """Test whether registering a new user initializes all progress values to 0.0""" clear_db() token = await register_user() headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"} for course in CourseEnum: if course != CourseEnum.All: response = client.get(f"/courseprogress/{course}", headers=headers) assert response.status_code == 200 response = response.json()[0] assert response["progress_value"] == 0.0 assert response["course"] == course @pytest.mark.asyncio async def test_get_all_returns_all(): """Test whether the 'All'-course fetches all course progress values""" clear_db() token = await register_user() headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"} response = client.get("/courseprogress/All", headers=headers) assert response.status_code == 200 response = response.json() for course in CourseEnum: if course != CourseEnum.All: 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 async def test_get_nonexisting_course_should_fail(): """Test whether fetching the progress of a nonexisting course fails""" clear_db() token = await register_user() fake_course = "FakeCourse" headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"} response = client.get(f"/courseprogress/{fake_course}", headers=headers) assert response.status_code == 422 @pytest.mark.asyncio async def test_patch_course_progress(): """Test whether patching the progress value of a course works properly""" clear_db() token = await register_user() headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"} for course in CourseEnum: if course != CourseEnum.All: progress_value = random.uniform(0, 1) response = client.patch( f"/courseprogress/{course}", headers=headers, json={"progress_value": progress_value}, ) assert response.status_code == 200 assert response.json()[0]["progress_value"] == progress_value @pytest.mark.asyncio async def test_patch_all_should_patch_all_courses(): """Test whether patching the 'All'-course updates all progress values""" clear_db() token = await register_user() headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"} progress_value = random.uniform(0, 1) response = client.patch( "/courseprogress/All", headers=headers, json={"progress_value": progress_value}, ) assert response.status_code == 200 response = client.get("/courseprogress/All", headers=headers) assert response.status_code == 200 response = response.json() for course in CourseEnum: if course != CourseEnum.All: assert {"progress_value": progress_value, "course": course} in response @pytest.mark.asyncio async def test_patch_nonexisting_course_should_fail(): """Test whether patching a nonexisting course fails""" clear_db() token = await register_user() fake_course = "FakeCourse" headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"} progress_value = random.uniform(0, 1) response = client.patch( f"/courseprogress/{fake_course}", headers=headers, json={"progress_value": progress_value}, ) assert response.status_code == 422 @pytest.mark.asyncio async def test_patch_course_with_invalid_value_should_fail(): """Test whether patching a course progress value with an invalid value fails""" clear_db() token = await register_user() headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"} too_high_progress_value = random.uniform(0, 1) + 2 too_low_progress_value = random.uniform(0, 1) - 2 response = client.patch( "/courseprogress/All", headers=headers, json={"progress_value": too_high_progress_value}, ) assert response.status_code == 400 response = client.patch( "/courseprogress/All", headers=headers, json={"progress_value": too_low_progress_value}, ) 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