import random import pytest from src.enums import MinigameEnum from tests.base import client, password, register_user from tests.config.database import clear_db @pytest.mark.asyncio async def test_put_highscore(): """Test whether putting a new high score succeeds""" 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 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(): """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 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(): """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(): """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() headers = {"Content-Type": "application/json"} 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) ] for user, score in users_score_tuples: response = client.post( "/register", headers=headers, json={ "username": user, "password": password, "avatar_index": avatar_index, }, ) assert response.status_code == 200 token = response.json()["access_token"] response = client.put( f"/highscores/{minigame}", headers={ "Authorization": f"Bearer {token}", "Content-Type": "application/json", }, json={"score_value": score}, ) assert response.status_code == 200 response = client.get( f"/highscores/{minigame}?mine_only=false&nr_highest={int(nr_entries)}", headers={ "Authorization": f"Bearer {token}", "Content-Type": "application/json", }, ) 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