def test_make_move_draw_by_threefold_repetition(self):
        board = chess.Board()
        board.push_san("Nf3")
        board.push_san("Nf6")
        board.push_san("Ng1")
        board.push_san("Ng8")
        board.push_san("Nf3")
        board.push_san("Nf6")
        board.push_san("Ng1")
        game = Game()
        game.board = board
        game.player1 = FakeDiscordUser(id=1)
        game.player2 = FakeDiscordUser(id=2)
        game.current_player = game.player2

        chess_bot = Chess()
        chess_bot.games.append(game)

        self.assertFalse(chess_bot.is_game_over(game))

        result = asyncio.run(chess_bot.make_move(game, 'Ng8'))

        self.assertIsInstance(result, Game)
        self.assertEqual(len(chess_bot.games), 0)
        self.assertEqual(
            self.db_session.query(ChessGame).filter_by(result=0).count(), 1)
        self.assertTrue(chess_bot.is_game_over(result))
        self.assertEqual(result.result, '1/2-1/2')
    def test_make_move_legal_move_pve(self):
        board = chess.Board(
            'rn2kb1r/pp1qpppp/2ppbn2/1B6/3PP3/2N2N2/PPP2PPP/R1BQK2R w KQkq - 0 6'
        )
        game = Game()
        game.board = board
        game.player1 = FakeDiscordUser(id=1)
        game.player2 = FakeDiscordUser(id=2)
        game.current_player = game.player1
        game.cpu_level = 0

        chess_bot = Chess()
        chess_bot.games.append(game)
        chess_bot.stockfish_limit['time'] = 1
        result = asyncio.run(chess_bot.make_move(game, 'b5d3'))

        self.assertIsInstance(result, Game)
        if chess_bot.is_stockfish_enabled():
            self.assertEqual(len(result.board.move_stack), 2)
            self.assertEqual(result.current_player, game.player1)

        updated_chess_game = self.db_session.query(ChessGame).filter_by(
            player1_id=result.player1.id).first()
        updated_game_from_db = Game.from_chess_game_model(updated_chess_game)
        self.assertEqual(updated_game_from_db.board.move_stack,
                         result.board.move_stack)
    def test_make_move_illegal_move_in_players_turn(self):
        board = chess.Board()
        board.push_san("e4")
        board.push_san("e5")
        game = Game()
        game.board = board
        game.player1 = FakeDiscordUser(id=1)
        game.player2 = FakeDiscordUser(id=2)
        game.current_player = game.player1

        chess_bot = Chess()
        chess_bot.games.append(game)

        with self.assertRaises(InvalidMove) as e:
            asyncio.run(chess_bot.make_move(game, 'invalid'))

        self.assertEqual(len(game.board.move_stack), 2)
        self.assertEqual(game.current_player, game.player1)
    def test_make_move_finish_game(self):
        board = chess.Board()
        board.push_san("g4")
        board.push_san("e5")
        board.push_san("f4")
        game = Game()
        game.board = board
        game.player1 = FakeDiscordUser(id=1)
        game.player2 = FakeDiscordUser(id=2)
        game.current_player = game.player1

        chess_bot = Chess()
        chess_bot.games.append(game)
        result = asyncio.run(chess_bot.make_move(game, 'd8h4'))

        self.assertIsInstance(result, Game)
        self.assertEqual(len(chess_bot.games), 0)
        self.assertEqual(
            self.db_session.query(ChessGame).filter_by(result=-1).count(), 1)
        self.assertTrue(chess_bot.is_game_over(result))
        self.assertEqual(result.result, '0-1')
    def test_make_move_legal_san_move_in_players_turn(self):
        board = chess.Board()
        board.push_san("e4")
        board.push_san("e5")
        game = Game()
        game.board = board
        game.player1 = FakeDiscordUser(id=1)
        game.player2 = FakeDiscordUser(id=2)
        game.current_player = game.player1

        chess_bot = Chess()
        chess_bot.games.append(game)
        result = asyncio.run(chess_bot.make_move(game, 'Nf3'))

        self.assertIsInstance(result, Game)
        self.assertEqual(len(result.board.move_stack), 3)
        self.assertEqual(result.current_player, game.player2)

        updated_chess_game = self.db_session.query(ChessGame).filter_by(
            player1_id=result.player1.id).first()
        updated_game_from_db = Game.from_chess_game_model(updated_chess_game)
        self.assertEqual(updated_game_from_db.board.move_stack,
                         result.board.move_stack)