async def test_has_ai_players_not_rated(game): game.state = GameState.LOBBY add_players(game, 2, team=1) add_players(game, 2, team=2) game.AIs = {'IA Tech': {'Faction': 5, 'Color': 1, 'Team': 2, 'StartSpot': 2}, 'Oum-Ashavoh (IA Tech)': {'Army': 3}} await game.launch() await game.add_result(0, 1, 'VICTORY', 5) game.launched_at = time.time() - 60*20 # seconds await game.on_game_end() assert game.validity == ValidityState.HAS_AI_PLAYERS
async def test_ffa_not_rated(game): game.state = GameState.LOBBY add_players(game, 5, team=1) await game.launch() await game.add_result(0, 1, 'VICTORY', 5) game.launched_at = time.time() - 60*20 # seconds await game.on_game_end() assert game.validity == ValidityState.FFA_NOT_RANKED
async def test_ffa_not_rated(game): game.state = GameState.LOBBY add_players(game, 5, team=1) await game.launch() await game.add_result(0, 1, 'VICTORY', 5) game.launched_at = time.time() - 60 * 20 # seconds await game.on_game_end() assert game.validity == ValidityState.FFA_NOT_RANKED
async def test_single_team_not_rated(game): n_players = 4 game.state = GameState.LOBBY add_players(game, n_players, team=2) await game.launch() game.launched_at = time.time()-60*20 for i in range(n_players): await game.add_result(0, i+1, 'victory', 5) await game.on_game_end() assert game.validity is ValidityState.UNEVEN_TEAMS_NOT_RANKED
async def test_uneven_teams_not_rated(game): game.state = GameState.LOBBY add_players(game, 2, team=2) add_players(game, 3, team=3) await game.launch() await game.add_result(0, 1, 'VICTORY', 5) game.launched_at = time.time() - 60 * 20 # seconds await game.on_game_end() assert game.validity == ValidityState.UNEVEN_TEAMS_NOT_RANKED
async def test_uneven_teams_not_rated(game): game.state = GameState.LOBBY add_players(game, 2, team=2) add_players(game, 3, team=3) await game.launch() await game.add_result(0, 1, 'VICTORY', 5) game.launched_at = time.time() - 60*20 # seconds await game.on_game_end() assert game.validity == ValidityState.UNEVEN_TEAMS_NOT_RANKED
async def test_single_team_not_rated(game): n_players = 4 game.state = GameState.LOBBY add_players(game, n_players, team=2) await game.launch() game.launched_at = time.time() - 60 * 20 for i in range(n_players): await game.add_result(0, i + 1, 'victory', 5) await game.on_game_end() assert game.validity is ValidityState.UNEVEN_TEAMS_NOT_RANKED
async def test_game_not_ends_in_unilatery_agreed_draw(game: Game, players): game.state = GameState.LOBBY add_players(game, 2) await game.launch() game.launched_at = time.time() - 60 * 60 await game.add_result(players.hosting, 0, 'mutual_draw', 0) await game.add_result(players.joining, 1, 'victory', 10) await game.on_game_end() assert game.validity is not ValidityState.MUTUAL_DRAW
async def test_game_not_ends_in_unilatery_agreed_draw(game: Game, players): game.state = GameState.LOBBY add_players(game, 2) await game.launch() game.launched_at = time.time()-60*60 await game.add_result(players.hosting, 0, 'mutual_draw', 0) await game.add_result(players.joining, 1, 'victory', 10) await game.on_game_end() assert game.validity is not ValidityState.MUTUAL_DRAW
async def test_get_army_score_conflicting_results_tied(game): game.state = GameState.LOBBY add_players(game, 2, team=2) add_players(game, 2, team=3) await game.add_result(0, 0, 'victory', 1000) await game.add_result(1, 0, 'victory', 1234) await game.add_result(2, 1, 'defeat', 100) await game.add_result(3, 1, 'defeat', 123) # Choose the highest score assert game.get_army_score(0) == 1234 assert game.get_army_score(1) == 123
async def test_persist_results_not_called_with_no_results(game): game.state = GameState.LOBBY add_players(game, 5) game.persist_results = CoroMock() game.launched_at = time.time() - 60*20 await game.launch() await game.on_game_end() assert len(game.players) == 5 assert len(game._results) == 0 assert game.validity is ValidityState.UNKNOWN_RESULT game.persist_results.assert_not_called()
async def test_persist_results_not_called_with_no_results(game): game.state = GameState.LOBBY add_players(game, 5) game.persist_results = CoroMock() game.launched_at = time.time() - 60 * 20 await game.launch() await game.on_game_end() assert len(game.players) == 5 assert len(game._results) == 0 assert game.validity is ValidityState.UNKNOWN_RESULT game.persist_results.assert_not_called()
async def test_persist_results_called_with_two_players(game): game.clear_data() game.state = GameState.LOBBY add_players(game, 2) await game.launch() assert len(game.players) == 2 await game.add_result(0, 1, 'VICTORY', 5) await game.on_game_end() assert game.get_army_score(1) == 5 assert len(game.players) == 2 await game.load_results() assert game.get_army_score(1) == 5
async def test_persist_results_called_with_two_players(game): await game.clear_data() game.state = GameState.LOBBY add_players(game, 2) await game.launch() assert len(game.players) == 2 await game.add_result(0, 1, 'VICTORY', 5) await game.on_game_end() assert game.get_army_score(1) == 5 assert len(game.players) == 2 await game.load_results() assert game.get_army_score(1) == 5
async def test_persist_results_called_for_unranked(game): await game.clear_data() game.state = GameState.LOBBY add_players(game, 2) await game.launch() game.validity = ValidityState.BAD_UNIT_RESTRICTIONS assert len(game.players) == 2 await game.add_result(0, 1, 'victory', 5) await game.on_game_end() assert game.get_army_score(1) == 5 assert len(game.players) == 2 await game.load_results() assert game.get_army_score(1) == 5
async def test_get_army_score_conflicting_results_clear_winner(game): game.state = GameState.LOBBY add_players(game, 3, team=2) add_players(game, 3, team=3) await game.launch() await game.add_result(0, 0, 'victory', 1000) await game.add_result(1, 0, 'victory', 1234) await game.add_result(2, 0, 'victory', 1234) await game.add_result(3, 1, 'defeat', 100) await game.add_result(4, 1, 'defeat', 123) await game.add_result(5, 1, 'defeat', 100) # Choose the most frequently reported score assert game.get_army_score(0) == 1234 assert game.get_army_score(1) == 100
async def test_on_game_end_calls_rate_game_with_two_players(game): await game.clear_data() game.rate_game = CoroMock() game.state = GameState.LOBBY add_players(game, 2) await game.launch() assert len(game.players) == 2 await game.add_result(0, 1, 'victory', 10) await game.add_result(1, 2, 'defeat', -10) await game.on_game_end() assert game.state == GameState.ENDED game.rate_game.assert_any_call() assert game.validity is ValidityState.VALID
async def test_validate_game_settings(game: Game): settings = [ ('Victory', Victory.SANDBOX, ValidityState.WRONG_VICTORY_CONDITION), ('FogOfWar', 'none', ValidityState.NO_FOG_OF_WAR), ('CheatsEnabled', 'true', ValidityState.CHEATS_ENABLED), ('PrebuiltUnits', 'On', ValidityState.PREBUILT_ENABLED), ('NoRushOption', 20, ValidityState.NORUSH_ENABLED), ('RestrictedCategories', 1, ValidityState.BAD_UNIT_RESTRICTIONS), ('TeamLock', 'unlocked', ValidityState.UNLOCKED_TEAMS) ] game.state = GameState.LOBBY add_players(game, 2) await check_game_settings(game, settings) game.validity = ValidityState.VALID await game.validate_game_settings() assert game.validity is ValidityState.VALID
async def test_game_ends_in_mutually_agreed_draw(game: Game): game.state = GameState.LOBBY players = add_players(game, 2) await game.launch() game.launched_at = time.time() - 60 * 60 await game.add_result(players[0], 0, 'mutual_draw', 0) await game.add_result(players[1], 1, 'mutual_draw', 0) await game.on_game_end() assert game.validity is ValidityState.MUTUAL_DRAW
async def test_game_ends_in_mutually_agreed_draw(game: Game): game.state = GameState.LOBBY players = add_players(game, 2) await game.launch() game.launched_at = time.time()-60*60 await game.add_result(players[0], 0, 'mutual_draw', 0) await game.add_result(players[1], 1, 'mutual_draw', 0) await game.on_game_end() assert game.validity is ValidityState.MUTUAL_DRAW
async def test_report_army_stats_sends_stats_for_defeated_player(game: Game): game.state = GameState.LOBBY players = add_players(game, 2) await game.launch() await game.add_result(0, 1, 'defeat', -1) with open("tests/data/game_stats_simple_win.json", "r") as stats_file: stats = stats_file.read() await game.report_army_stats(stats) game._game_stats_service.process_game_stats.assert_called_once_with(players[1], game, stats)
async def test_game_get_army_result_takes_most_reported_result(game): game.state = GameState.LOBBY players = add_players(game, 1) await game.add_result(0, 0, 'defeat', 0) await game.add_result(0, 0, 'defeat', 0) await game.add_result(0, 0, 'victory', 0) assert game.get_army_result(players[0]) == 'defeat' await game.add_result(0, 0, 'victory', 0) await game.add_result(0, 0, 'victory', 0) assert game.get_army_result(players[0]) == 'victory'
async def test_multi_team_not_rated(game): game.state = GameState.LOBBY add_players(game, 2, team=1) add_players(game, 2, team=2) add_players(game, 2, team=3) await game.launch() await game.add_result(0, 1, 'VICTORY', 5) game.launched_at = time.time() - 60 * 20 # seconds await game.on_game_end() assert game.validity == ValidityState.MULTI_TEAM
async def test_global_rating_higher_after_custom_game_win(custom_game: CustomGame): game = custom_game game.state = GameState.LOBBY players = add_players(game, 2) game.set_player_option(players[0].id, 'Team', 1) game.set_player_option(players[1].id, 'Team', 2) old_mean = players[0].global_rating[0] await game.launch() game.launched_at = time.time() - 60*20 # seconds await game.add_result(0, 0, 'victory', 5) await game.add_result(0, 1, 'defeat', -5) await game.on_game_end() assert game.validity is ValidityState.VALID assert players[0].global_rating[0] > old_mean
async def test_global_rating_higher_after_custom_game_win( custom_game: CustomGame): game = custom_game game.state = GameState.LOBBY players = add_players(game, 2) game.set_player_option(players[0].id, 'Team', 1) game.set_player_option(players[1].id, 'Team', 2) old_mean = players[0].global_rating[0] await game.launch() game.launched_at = time.time() - 60 * 20 # seconds await game.add_result(0, 0, 'victory', 5) await game.add_result(0, 1, 'defeat', -5) await game.on_game_end() assert game.validity is ValidityState.VALID assert players[0].global_rating[0] > old_mean
async def test_players_exclude_observers(game: Game): game.state = GameState.LOBBY players = add_players(game, 2) obs = Player(id=3, login='******', global_rating=(1500, 500)) game.game_service.player_service[obs.id] = obs gc = mock_game_connection(state=GameConnectionState.CONNECTED_TO_HOST, player=obs) game.set_player_option(obs.id, 'Army', -1) game.set_player_option(obs.id, 'StartSpot', -1) game.set_player_option(obs.id, 'Team', 0) game.set_player_option(obs.id, 'Faction', 0) game.set_player_option(obs.id, 'Color', 0) game.add_game_connection(gc) await game.launch() assert game.players == frozenset(players)
async def test_players_exclude_observers(game: Game): game.state = GameState.LOBBY players = add_players(game, 2) obs = Player(id=3, login='******', global_rating=(1500, 500)) game.game_service.player_service[obs.id] = obs gc = make_mock_game_connection(state=GameConnectionState.CONNECTED_TO_HOST, player=obs) game.set_player_option(obs.id, 'Army', -1) game.set_player_option(obs.id, 'StartSpot', -1) game.set_player_option(obs.id, 'Team', 0) game.set_player_option(obs.id, 'Faction', 0) game.set_player_option(obs.id, 'Color', 0) game.add_game_connection(gc) await game.launch() assert game.players == frozenset(players)
async def test_partial_stats_not_affecting_rating_persistence(custom_game, event_service, achievement_service): from server.stats.game_stats_service import GameStatsService game = custom_game game._game_stats_service = GameStatsService(event_service, achievement_service) game.state = GameState.LOBBY players = add_players(game, 2) game.set_player_option(players[0].id, 'Team', 2) game.set_player_option(players[1].id, 'Team', 3) old_mean = players[0].global_rating[0] await game.launch() game.launched_at = time.time()-60*60 await game.add_result(0, 0, 'victory', 10) await game.add_result(0, 1, 'defeat', -10) await game.report_army_stats({'stats': {'Player 1': {}}}) await game.on_game_end() assert game.validity is ValidityState.VALID assert players[0].global_rating[0] > old_mean
async def test_rate_game(laddergame: LadderGame, db_pool): async with db.db_pool.get() as conn: cursor = await conn.cursor() # TODO remove as soon as we have isolated tests (transactions) await cursor.execute("DELETE FROM game_stats WHERE id = %s", laddergame.id) await cursor.execute("DELETE FROM game_player_stats WHERE gameId = %s", laddergame.id) laddergame.state = GameState.LOBBY players = add_players(laddergame, 2) laddergame.set_player_option(players[0].id, 'Team', 1) laddergame.set_player_option(players[1].id, 'Team', 2) player_1_old_mean = players[0].ladder_rating[0] player_2_old_mean = players[1].ladder_rating[0] await laddergame.launch() laddergame.launched_at = time.time() - 60 * 20 await laddergame.add_result(0, 0, 'victory', 5) await laddergame.add_result(0, 1, 'defeat', -5) await laddergame.on_game_end() assert laddergame.validity is ValidityState.VALID assert players[0].ladder_rating[0] > player_1_old_mean assert players[1].ladder_rating[0] < player_2_old_mean async with db.db_pool.get() as conn: cursor = await conn.cursor(DictCursor) await cursor.execute( "SELECT mean, deviation, after_mean, after_deviation FROM game_player_stats WHERE gameid = %s", laddergame.id) result = await cursor.fetchall() assert result[0]['mean'] == 1500 assert result[0]['deviation'] == 500 assert result[0]['after_mean'] > result[0]['mean'] assert result[0]['after_deviation'] < result[0]['deviation'] assert result[1]['mean'] == 1500 assert result[1]['deviation'] == 500 assert result[1]['after_mean'] < result[0]['mean'] assert result[1]['after_deviation'] < result[0]['deviation']
async def test_rate_game(laddergame: LadderGame, db_pool): async with db.db_pool.get() as conn: cursor = await conn.cursor() # TODO remove as soon as we have isolated tests (transactions) await cursor.execute("DELETE FROM game_stats WHERE id = %s", laddergame.id) await cursor.execute("DELETE FROM game_player_stats WHERE gameId = %s", laddergame.id) laddergame.state = GameState.LOBBY players = add_players(laddergame, 2) laddergame.set_player_option(players[0].id, 'Team', 1) laddergame.set_player_option(players[1].id, 'Team', 2) player_1_old_mean = players[0].ladder_rating[0] player_2_old_mean = players[1].ladder_rating[0] await laddergame.launch() laddergame.launched_at = time.time() - 60*20 await laddergame.add_result(0, 0, 'victory', 5) await laddergame.add_result(0, 1, 'defeat', -5) await laddergame.on_game_end() assert laddergame.validity is ValidityState.VALID assert players[0].ladder_rating[0] > player_1_old_mean assert players[1].ladder_rating[0] < player_2_old_mean async with db.db_pool.get() as conn: cursor = await conn.cursor(DictCursor) await cursor.execute("SELECT mean, deviation, after_mean, after_deviation FROM game_player_stats WHERE gameid = %s", laddergame.id) result = await cursor.fetchall() assert result[0]['mean'] == 1500 assert result[0]['deviation'] == 500 assert result[0]['after_mean'] > result[0]['mean'] assert result[0]['after_deviation'] < result[0]['deviation'] assert result[1]['mean'] == 1500 assert result[1]['deviation'] == 500 assert result[1]['after_mean'] < result[0]['mean'] assert result[1]['after_deviation'] < result[0]['deviation']
async def test_persist_rating_victory(laddergame: LadderGame, db_engine): async with db_engine.acquire() as conn: # TODO remove as soon as we have isolated tests (transactions) await conn.execute("DELETE FROM game_player_stats WHERE gameId = %s", laddergame.id) await conn.execute("DELETE FROM game_stats WHERE id = %s", laddergame.id) laddergame.state = GameState.LOBBY players = add_players(laddergame, 2) laddergame.set_player_option(players[0].id, 'Team', 1) laddergame.set_player_option(players[1].id, 'Team', 2) async with db_engine.acquire() as conn: result = await conn.execute( text("SELECT id, numGames, winGames FROM ladder1v1_rating WHERE id in :ids ORDER BY id"), ids=tuple([players[0].id, players[1].id]) ) result_before = await result.fetchall() await laddergame.launch() laddergame.launched_at = time.time() - 60*20 await laddergame.add_result(0, 0, 'victory', 5) await laddergame.add_result(0, 1, 'defeat', -5) await laddergame.on_game_end() assert laddergame.validity is ValidityState.VALID async with db_engine.acquire() as conn: result = await conn.execute( text("SELECT id, numGames, winGames FROM ladder1v1_rating WHERE id in :ids ORDER BY id"), ids=tuple([players[0].id, players[1].id]) ) result_after = await result.fetchall() assert result_after[0]['numGames'] == result_before[0]['numGames'] + 1 assert result_after[1]['numGames'] == result_before[1]['numGames'] + 1 assert result_after[0]['winGames'] == result_before[0]['winGames'] + 1 assert result_after[1]['winGames'] == result_before[1]['winGames']
def test_is_even(game: Game): game.state = GameState.LOBBY add_players(game, 4, team=2) add_players(game, 4, team=3) assert game.is_even
def test_is_even_single_player(game: Game): game.state = GameState.LOBBY add_players(game, 2, team=2) assert not game.is_even
def test_is_even_ffa(game: Game): game.state = GameState.LOBBY # Team 1 is the special "-" team add_players(game, 5, team=1) assert game.is_even