Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tests for lib.lichess and lib.model #1051

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def is_supported_mode(self, challenge_cfg: Configuration) -> bool:
return ("rated" if self.rated else "casual") in challenge_cfg.modes

def is_supported_recent(self, config: Configuration, recent_bot_challenges: defaultdict[str, list[Timer]]) -> bool:
"""Check whether we have played a lot of games with this opponent recently. Only used when the oppoennt is a BOT."""
"""Check whether we have played a lot of games with this opponent recently. Only used when the opponent is a BOT."""
# Filter out old challenges
recent_bot_challenges[self.challenger.name] = [timer for timer
in recent_bot_challenges[self.challenger.name]
Expand Down
4 changes: 3 additions & 1 deletion lib/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class PerfType(TypedDict, total=False):
rd: int
sd: int
prov: bool
prog: int


class ProfileType(TypedDict, total=False):
Expand Down Expand Up @@ -69,6 +70,7 @@ class UserProfileType(TypedDict, total=False):
following: bool
blocking: bool
followsYou: bool
count: dict[str, int]


class ReadableType(TypedDict):
Expand Down Expand Up @@ -121,7 +123,7 @@ class InfoStrDict(TypedDict, total=False):
class PlayerType(TypedDict, total=False):
"""Type hint for information on a player."""

title: str
title: Optional[str]
rating: int
provisional: bool
aiLevel: int
Expand Down
49 changes: 49 additions & 0 deletions test_bot/test_lichess.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
"""Tests for the lichess communication."""

from lib import lichess
import logging
import os
import pytest


def test_lichess() -> None:
"""Test the lichess communication."""
token = os.getenv("LICHESS_BOT_TEST_TOKEN")
if token is None:
pytest.skip("Lichess-bot test token must be set.")
li = lichess.Lichess(token, "https://lichess.org/", "0.0.0", logging.DEBUG, 3)
assert len(li.get_online_bots()) > 20
MarkZH marked this conversation as resolved.
Show resolved Hide resolved
profile = li.get_profile()
profile['seenAt'] = 1700000000000
assert profile == {'blocking': False,
'count': {'ai': 3, 'all': 12, 'bookmark': 0, 'draw': 1, 'drawH': 1, 'import': 0,
'loss': 8, 'lossH': 5, 'me': 0, 'playing': 0, 'rated': 0, 'win': 3, 'winH': 3},
'createdAt': 1627834995597, 'followable': True, 'following': False, 'id': 'badsunfish',
'perfs': {'blitz': {'games': 0, 'prog': 0, 'prov': True, 'rating': 1500, 'rd': 500},
'bullet': {'games': 0, 'prog': 0, 'prov': True, 'rating': 1500, 'rd': 500},
'classical': {'games': 0, 'prog': 0, 'prov': True, 'rating': 1500, 'rd': 500},
'correspondence': {'games': 0, 'prog': 0, 'prov': True, 'rating': 1500, 'rd': 500},
'rapid': {'games': 0, 'prog': 0, 'prov': True, 'rating': 1500, 'rd': 500}},
'playTime': {'total': 1873, 'tv': 0}, 'seenAt': 1700000000000, 'title': 'BOT',
'url': 'https://lichess.org/@/BadSunfish', 'username': 'BadSunfish'}
assert li.get_ongoing_games() == []
assert li.is_online("NNWithSF") is False
assert li.get_public_data("lichapibot") == {'blocking': False,
'count': {'ai': 1, 'all': 15774, 'bookmark': 0, 'draw': 3009, 'drawH': 3009,
'import': 0, 'loss': 6423, 'lossH': 6423,
'me': 0, 'playing': 0, 'rated': 15121, 'win': 6342, 'winH': 6341},
'createdAt': 1524037267522, 'followable': True, 'following': False,
'id': 'lichapibot',
'perfs': {'blitz': {'games': 2430, 'prog': 3, 'prov': True, 'rating': 2388,
'rd': 142},
'bullet': {'games': 7293, 'prog': 9, 'prov': True, 'rating': 2298,
'rd': 133},
'classical': {'games': 0, 'prog': 0, 'prov': True, 'rating': 1500,
'rd': 500},
'correspondence': {'games': 0, 'prog': 0, 'prov': True,
'rating': 1500, 'rd': 500},
'rapid': {'games': 993, 'prog': -80, 'prov': True, 'rating': 2363,
'rd': 149}},
'playTime': {'total': 4111502, 'tv': 1582068}, 'profile': {},
'seenAt': 1669272254317, 'title': 'BOT', 'tosViolation': True,
'url': 'https://lichess.org/@/lichapibot', 'username': 'lichapibot'}
85 changes: 85 additions & 0 deletions test_bot/test_model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
"""Tests for the models."""

import datetime
from lib import model
import yaml
from lib import config
from collections import defaultdict
from lib.timer import Timer
from lib.types import ChallengeType, UserProfileType, GameEventType, PlayerType


def test_challenge() -> None:
"""Test the challenge model."""
challenge: ChallengeType = {"id": "zzzzzzzz", "url": "https://lichess.org/zzzzzzzz", "status": "created",
"challenger": {"id": "c", "name": "c", "rating": 2000, "title": None, "online": True},
"destUser": {"id": "b", "name": "b", "rating": 3000, "title": "BOT", "online": True},
"variant": {"key": "standard", "name": "Standard", "short": "Std"}, "rated": False,
"speed": "bullet",
"timeControl": {"type": "clock", "limit": 90, "increment": 1, "show": "1.5+1"},
"color": "random", "finalColor": "white", "perf": {"icon": "\ue032", "name": "Bullet"}}
user_profile: UserProfileType = {"id": "b", "username": "b",
"perfs": {"bullet": {"games": 100, "rating": 3000, "rd": 150, "prog": -10},
"blitz": {"games": 100, "rating": 3000, "rd": 150, "prog": -10},
"rapid": {"games": 100, "rating": 3000, "rd": 150, "prog": -10},
"classical": {"games": 100, "rating": 3000, "rd": 150, "prog": -10},
"correspondence": {"games": 100, "rating": 3000, "rd": 150, "prog": -10},
"antichess": {"games": 100, "rating": 3000, "rd": 150, "prog": -10,
"prov": True}},
"title": "BOT", "createdAt": 1500000000000,
"profile": {"bio": "This is my bio",
"links": "https://github.com/lichess-bot-devs/lichess-bot"},
"seenAt": 1700000000000, "playTime": {"total": 1000000, "tv": 10000},
"url": "https://lichess.org/@/b",
"count": {"all": 600, "rated": 500, "ai": 50, "draw": 200, "drawH": 50, "loss": 50,
"lossH": 50, "win": 250, "winH": 200, "bookmark": 0, "playing": 0,
"import": 0, "me": 0},
"followable": True, "following": False, "blocking": False}

with open("./config.yml.default") as file:
CONFIG = yaml.safe_load(file)
CONFIG["token"] = ""
CONFIG["challenge"]["allow_list"] = []
CONFIG["challenge"]["block_list"] = []
configuration = config.Configuration(CONFIG).challenge
recent_challenges: defaultdict[str, list[Timer]] = defaultdict()
recent_challenges["c"] = []

challenge_model = model.Challenge(challenge, user_profile)
assert challenge_model.id == "zzzzzzzz"
assert challenge_model.rated is False
assert challenge_model.variant == "standard"
assert challenge_model.speed == "bullet"
assert challenge_model.time_control["show"] == "1.5+1"
assert challenge_model.color == "white"
assert challenge_model.is_supported(configuration, recent_challenges) == (True, "")

CONFIG["challenge"]["min_base"] = 120
assert challenge_model.is_supported(configuration, recent_challenges) == (False, "timeControl")


def test_game() -> None:
"""Test the game model."""
game: GameEventType = {"id": "zzzzzzzz", "variant": {"key": "standard", "name": "Standard", "short": "Std"},
"speed": "bullet", "perf": {"name": "Bullet"}, "rated": False, "createdAt": 1700000000000,
"white": {"id": "c", "name": "c", "title": None, "rating": 2000},
"black": {"id": "b", "name": "b", "title": "BOT", "rating": 3000},
"initialFen": "startpos", "clock": {"initial": 90000, "increment": 1000}, "type": "gameFull",
"state": {"type": "gameState", "moves": "", "wtime": 90000, "btime": 90000, "winc": 1000,
"binc": 1000, "status": "started"}}
username = "b"
base_url = "https://lichess.org/"
abort_time = datetime.timedelta(seconds=30)

game_model = model.Game(game, username, base_url, abort_time)
assert game_model.id == "zzzzzzzz"
assert game_model.mode == "casual"
assert game_model.is_white is False


def test_player() -> None:
"""Test the player model."""
player: PlayerType = {"id": "b", "name": "b", "rating": 3000, "title": "BOT", "online": True}
player_model = model.Player(player)
assert player_model.is_bot is True
assert str(player_model) == "BOT b (3000)"
Loading