First tests for game stats

pull/124/head
stijndcl 2022-07-30 18:27:58 +02:00
parent bf41acd9f4
commit b74f794639
5 changed files with 64 additions and 7 deletions

View File

@ -16,7 +16,7 @@ async def add_dad_joke(session: AsyncSession, joke: str) -> DadJoke:
return dad_joke return dad_joke
async def get_random_dad_joke(session: AsyncSession) -> DadJoke: async def get_random_dad_joke(session: AsyncSession) -> DadJoke: # pragma: no cover # randomness is untestable
"""Return a random database entry""" """Return a random database entry"""
statement = select(DadJoke).order_by(func.random()) statement = select(DadJoke).order_by(func.random())
row = (await session.execute(statement)).first() row = (await session.execute(statement)).first()

View File

@ -24,15 +24,15 @@ async def get_game_stats(database: MongoDatabase, user_id: int) -> GameStats:
return stats return stats
async def complete_wordle_game(database: MongoDatabase, user_id: int, win: bool, guesses: int): async def complete_wordle_game(database: MongoDatabase, user_id: int, win: bool, guesses: int = 0):
"""Update the user's Wordle stats""" """Update the user's Wordle stats"""
stats = await get_game_stats(database, user_id) stats = await get_game_stats(database, user_id)
update: dict[str, dict[str, Union[int, datetime.datetime]]] = {"$inc": {"wordle.games": 1}} update: dict[str, dict[str, Union[int, datetime.datetime]]] = {"$inc": {"wordle.games": 1}, "$set": {}}
if win: if win:
update["$inc"]["wordle.wins"] = 1 update["$inc"]["wordle.wins"] = 1
update["$inc"][f"wordle.guess_distribution.{guesses}"] = 1 update["$inc"][f"wordle.guess_distribution.{guesses - 1}"] = 1
# Update streak # Update streak
today = today_only_date() today = today_only_date()

View File

@ -7,8 +7,9 @@ LOCAL_TIMEZONE = zoneinfo.ZoneInfo("Europe/Brussels")
def today_only_date() -> datetime.datetime: def today_only_date() -> datetime.datetime:
"""Mongo can't handle datetime.date, so we need datetime """Mongo can't handle datetime.date, so we need a datetime instance
We do, however, only care about the date, so remove all the rest We do, however, only care about the date, so remove all the rest
""" """
return datetime.datetime.today().replace(hour=0, minute=0, second=0, microsecond=0) today = datetime.date.today()
return datetime.datetime(year=today.year, month=today.month, day=today.day)

View File

@ -20,6 +20,7 @@ omit = [
"./didier/utils/discord/colours.py", "./didier/utils/discord/colours.py",
"./didier/utils/discord/constants.py", "./didier/utils/discord/constants.py",
"./didier/utils/discord/flags/*", "./didier/utils/discord/flags/*",
"./didier/views/modals/*"
] ]
[tool.isort] [tool.isort]

View File

@ -1,8 +1,63 @@
import pytest import pytest
from freezegun import freeze_time
from database.crud import game_stats as crud
from database.mongo_types import MongoDatabase from database.mongo_types import MongoDatabase
from database.schemas.mongo.game_stats import GameStats
from database.utils.datetime import today_only_date
async def insert_game_stats(mongodb: MongoDatabase, stats: GameStats):
"""Helper function to insert some stats"""
collection = mongodb[GameStats.collection()]
await collection.insert_one(stats.dict(by_alias=True))
@pytest.mark.mongo @pytest.mark.mongo
async def test_get_stats_non_existent(mongodb: MongoDatabase, test_user_id: int): async def test_get_stats_non_existent_creates(mongodb: MongoDatabase, test_user_id: int):
"""Test getting a user's stats when the db is empty""" """Test getting a user's stats when the db is empty"""
collection = mongodb[GameStats.collection()]
assert await collection.find_one({"user_id": test_user_id}) is None
await crud.get_game_stats(mongodb, test_user_id)
assert await collection.find_one({"user_id": test_user_id}) is not None
@pytest.mark.mongo
async def test_get_stats_existing_returns(mongodb: MongoDatabase, test_user_id: int):
"""Test getting a user's stats when there's already an entry present"""
stats = GameStats(user_id=test_user_id)
stats.wordle.games = 20
await insert_game_stats(mongodb, stats)
found_stats = await crud.get_game_stats(mongodb, test_user_id)
assert found_stats.wordle.games == 20
@pytest.mark.mongo
@freeze_time("2022-07-30")
async def test_complete_wordle_game_won(mongodb: MongoDatabase, test_user_id: int):
"""Test completing a wordle game when you win"""
await crud.complete_wordle_game(mongodb, test_user_id, win=True, guesses=2)
stats = await crud.get_game_stats(mongodb, test_user_id)
assert stats.wordle.guess_distribution == [0, 1, 0, 0, 0, 0]
assert stats.wordle.games == 1
assert stats.wordle.wins == 1
assert stats.wordle.current_streak == 1
assert stats.wordle.max_streak == 1
assert stats.wordle.last_win == today_only_date()
@pytest.mark.mongo
@freeze_time("2022-07-30")
async def test_complete_wordle_game_lost(mongodb: MongoDatabase, test_user_id: int):
"""Test completing a wordle game when you lose"""
stats = GameStats(user_id=test_user_id)
stats.wordle.current_streak = 10
await insert_game_stats(mongodb, stats)
await crud.complete_wordle_game(mongodb, test_user_id, win=False)
stats = await crud.get_game_stats(mongodb, test_user_id)
# Check that streak was broken
assert stats.wordle.current_streak == 0
assert stats.wordle.games == 1
assert stats.wordle.guess_distribution == [0, 0, 0, 0, 0, 0]