import random import pytest from src.enums import MinigameEnum from tests.base import (avatar_index, client, get_headers, password, register_user) from tests.config.database import clear_db @pytest.mark.asyncio async def test_put_highscore_should_succeed(): """Test whether putting a new high score succeeds""" clear_db() token = await register_user() headers = get_headers(token) 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["score_value"] == score_value @pytest.mark.asyncio async def test_put_lower_highscore_should_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 = get_headers(token) 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["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["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 = get_headers(token) 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 = get_headers() 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 = get_headers() 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&amount={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 = get_headers(token) response = client.get( f"/highscores/{fake_minigame}", headers=headers, ) assert response.status_code == 422 response = client.get( f"/highscores/{fake_minigame}?mine_only=false&amount={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 = get_headers(token) for minigame in MinigameEnum: response = client.get( f"/highscores/{minigame}?amount={random.randint(-100, 0)}", headers=headers, ) assert response.status_code == 400 @pytest.mark.asyncio async def test_get_highscores_should_succeed_with_default_value(): """Test whether fetching high scores without passing an explicit amount still succeeds""" clear_db() token = await register_user() headers = get_headers(token) 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_should_return_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 = get_headers() for minigame in MinigameEnum: clear_db() nr_entries = random.randint(5, 10) 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=get_headers(token), json={"score_value": score}, ) assert response.status_code == 200 response = client.get( f"/highscores/{minigame}?mine_only=false&amount={int(nr_entries)}", headers=get_headers(token), ) 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"] response = client.get( f"/highscores/{minigame}?most_recent=true&mine_only=false&amount={int(nr_entries)}", headers=get_headers(token), ) assert response.status_code == 200 response = response.json() assert len(response) == nr_entries for i in range(1, len(response)): assert response[i]["time"] <= response[i - 1]["time"] @pytest.mark.asyncio async def test_get_own_existing_high_score_should_succeed(): """Test whether fetching your own high score of a game succeeds""" clear_db() token = await register_user() headers = get_headers(token) 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 = get_headers(token) 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 = get_headers(token) for minigame in MinigameEnum: response = client.get( f"/highscores/{minigame}?amount={random.randint(2, 20)}", headers=headers, ) assert response.status_code == 400