def test_piece_and_square_ambiguous_move(self, mocker): fen = ( "rnbqk2r/pp2bppp/4pn2/1N1p4/2Pp4/4PN2/PP3PPP/R1BQKB1R w KQkq - 0 1" ) user = User(board=chess.Board(fen), color=chess.WHITE) querytext = "knight takes D4" params = {"pawn": "", "piece": "knight", "square": "D4"} mocker.patch("chess_server.main.get_user", return_value=user) mock_play_lan = mocker.patch("chess_server.main.Mediator.play_lan") mock_get_response = mocker.patch( "chess_server.main.get_response_for_google", return_value=self.result, ) req_data = get_dummy_webhook_request_for_google( session_id=self.session_id, action="piece_and_square", intent="piece_and_square", queryText=querytext, parameters=params, ) value = piece_and_square(req_data) assert value == self.result assert "ambiguous" in mock_get_response.call_args[1]["textToSpeech"] mock_play_lan.assert_not_called()
def test_simply_san_ambiguous_move(self, mocker): fen = ( "rnbqk2r/pp2bppp/4pn2/1N1p4/2Pp4/4PN2/PP3PPP/R1BQKB1R w KQkq - 0 1" ) user = User(board=chess.Board(fen), color=chess.WHITE) san = "Nxd4" mocker.patch("chess_server.main.get_user", return_value=user) mock_play_lan = mocker.patch("chess_server.main.Mediator.play_lan") mock_get_response = mocker.patch( "chess_server.main.get_response_for_google", return_value=self.result, ) req_data = get_dummy_webhook_request_for_google( session_id=self.session_id, action="simply_san", intent="simply_san", queryText=san, parameters={"san": san}, ) value = simply_san(req_data) assert value == self.result assert "ambiguous" in mock_get_response.call_args[1]["textToSpeech"] mock_play_lan.assert_not_called()
def test_simply_san_legal_move(self, mocker): fen = ( "rnbqk2r/pp2bppp/2p2n2/3p2B1/3P4/2NBP3/PP3PPP/R2QK1NR b KQkq - 0 1" ) user = User(board=chess.Board(fen), color=chess.BLACK) san = "O-O" mocker.patch("chess_server.main.get_user", return_value=user) mock_play_lan = mocker.patch("chess_server.main.Mediator.play_lan") mock_play_engine = mocker.patch( "chess_server.main.Mediator.play_engine_move_and_get_speech", return_value=self.engine_reply, ) mock_get_response = mocker.patch( "chess_server.main.get_response_for_google", return_value=self.result, ) req_data = get_dummy_webhook_request_for_google( session_id=self.session_id, action="simply_san", intent="simply_san", queryText=san, parameters={"san": san}, ) value = simply_san(req_data) assert value == self.result assert mock_get_response.call_args[1]["textToSpeech"].startswith( self.engine_reply) mock_play_lan.assert_called_with(self.session_id, san) mock_play_engine.assert_called_with(self.session_id)
def test_castle_illegal_move(self, mocker): user = User(board=chess.Board(), color=chess.WHITE) queryText = "Castle short" mock_get_user = mocker.patch("chess_server.main.get_user", return_value=user) mock_process_castle = mocker.patch( "chess_server.main.process_castle_by_querytext", return_value="illegal move", ) mock_get_response = mocker.patch( "chess_server.main.get_response_for_google", return_value=self.result, ) req_data = get_dummy_webhook_request_for_google( session_id=self.session_id, action="castle", intent="castle", queryText=queryText, parameters={}, ) value = castle(req_data) assert value == self.result mock_get_user.assert_called_with(self.session_id) mock_process_castle.assert_called_with(board=user.board, queryText=queryText) mock_get_response.assert_called_with( textToSpeech=RESPONSES["illegal_move"])
def test_piece_and_square_legal_move_promotion_to_knight_check( self, mocker): fen = "2b5/3P1kp1/5p2/8/3p3p/8/r7/2K5 w - - 1 39" user = User(board=chess.Board(fen), color=chess.BLACK) params = {"piece": "Knight", "pawn": "Pawn", "square": "D8"} querytext = "Pawn to D8 Knight check" lan = "d7-d8=N+" mocker.patch("chess_server.main.get_user", return_value=user) mock_play_lan = mocker.patch("chess_server.main.Mediator.play_lan") mock_play_engine = mocker.patch( "chess_server.main.Mediator.play_engine_move_and_get_speech", return_value=self.engine_reply, ) mock_get_response = mocker.patch( "chess_server.main.get_response_for_google", return_value=self.result, ) req_data = get_dummy_webhook_request_for_google( session_id=self.session_id, action="piece_and_square", intent="piece_and_square", queryText=querytext, parameters=params, ) value = piece_and_square(req_data) assert value == self.result assert mock_get_response.call_args[1]["textToSpeech"].startswith( self.engine_reply) mock_play_lan.assert_called_with(self.session_id, lan) mock_play_engine.assert_called_with(self.session_id)
def test_simply_san_uppercase(self, mocker): fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1" user = User(board=chess.Board(fen), color=chess.WHITE) san = "E4" lan = "e2-e4" mocker.patch("chess_server.main.get_user", return_value=user) mock_play_lan = mocker.patch("chess_server.main.Mediator.play_lan") mock_play_engine = mocker.patch( "chess_server.main.Mediator.play_engine_move_and_get_speech", return_value=self.engine_reply, ) mock_get_response = mocker.patch( "chess_server.main.get_response_for_google", return_value=self.result, ) req_data = get_dummy_webhook_request_for_google( session_id=self.session_id, action="simply_san", intent="simply_san", queryText=san, parameters={"san": san}, ) value = simply_san(req_data) assert value == self.result assert mock_get_response.call_args[1]["textToSpeech"].startswith( self.engine_reply) mock_play_lan.assert_called_with(self.session_id, lan) mock_play_engine.assert_called_with(self.session_id)
def test_two_squares_illegal_move(self, mocker): user = User(board=chess.Board(), color=chess.WHITE) params = {"squares": ["a1", "b5"], "piece": "rook"} mock_get_user = mocker.patch("chess_server.main.get_user", return_value=user) mock_two_squares_to_lan = mocker.patch( "chess_server.main.two_squares_and_piece_to_lan", return_value="illegal move", ) mock_get_response = mocker.patch( "chess_server.main.get_response_for_google", return_value=self.result, ) req_data = get_dummy_webhook_request_for_google( session_id=self.session_id, action="two_squares", intent="two_squares", queryText="rook from a1 to b5", parameters=params, ) value = two_squares(req_data) assert value == self.result mock_get_user.assert_called_with(self.session_id) mock_two_squares_to_lan.assert_called_with(board=user.board, squares=params["squares"], piece=params["piece"]) mock_get_response.assert_called()
def test_delete_user_multiple_entries(context): session_id = get_random_session_id() board = chess.Board() color = chess.WHITE create_user(session_id, board, color) # Create another user session_id2 = get_random_session_id() board2 = chess.Board() color2 = chess.BLACK board2.push_san("e4") board2.push_san("d5") create_user(session_id2, board2, color2) # Delete first user delete_user(session_id) assert exists_in_db(session_id) is False # Verify that no other changes were made assert UserModel.query.count() == 1 assert get_user(session_id2) == User(board2, color2)
def test_piece_and_square_unexpected(self, mocker): fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1" user = User(board=chess.Board(fen), color=chess.BLACK) querytext = "Gibberish and then e4" params = {"piece": "", "pawn": "", "square": "e4"} mocker.patch("chess_server.main.get_user", return_value=user) mock_handle_san = mocker.patch( "chess_server.main.handle_san_and_get_response_kwargs") mock_get_response = mocker.patch( "chess_server.main.get_response_for_google", return_value=self.result, ) req_data = get_dummy_webhook_request_for_google( session_id=self.session_id, action="piece_and_square", intent="piece_and_square", queryText=querytext, parameters=params, ) value = piece_and_square(req_data) assert value == self.result assert (mock_get_response.call_args[1]["textToSpeech"] == "Sorry, can you say that again?") mock_handle_san.assert_not_called()
def test_piece_and_square_illegal_move(self, mocker): fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1" user = User(board=chess.Board(fen), color=chess.WHITE) querytext = "pawn to g5" params = {"piece": "", "pawn": "pawn", "square": "g5"} mocker.patch("chess_server.main.get_user", return_value=user) mock_play_lan = mocker.patch("chess_server.main.Mediator.play_lan") mock_get_response = mocker.patch( "chess_server.main.get_response_for_google", return_value=self.result, ) req_data = get_dummy_webhook_request_for_google( session_id=self.session_id, action="piece_and_square", intent="piece_and_square", queryText=querytext, parameters=params, ) value = piece_and_square(req_data) assert value == self.result assert "not legal" in mock_get_response.call_args[1]["textToSpeech"] mock_play_lan.assert_not_called()
def test_get_result_comment_game_is_not_over_as_white(self): user = User(board=chess.Board(), color=chess.WHITE) expected = None result = get_result_comment(user=user) self.assertEqual(result, expected)
def test_get_user(context): session_id = get_random_session_id() board = chess.Board() color = chess.BLACK create_user(session_id, board, color) assert get_user(session_id) == User(board, color)
def setup_method(self): self.session_id = get_random_session_id() self.user = User(board=chess.Board(), color=chess.WHITE) self.result = {"foo": "bar"} self.image = Image(url="http://testserver/img.png", accessibilityText="Hello World") self.card = BasicCard(image=self.image, formattedText="spam ham and eggs")
def test_two_squares_game_ends_after_engine_move(self, mocker): user = User(board=chess.Board(), color=chess.BLACK) squares = ["f6", "e7"] piece = "queen" move_lan = "Qf6-e7#" params = {"squares": squares, "piece": piece} mock_get_user = mocker.patch("chess_server.main.get_user", return_value=user) mock_del_user = mocker.patch("chess_server.main.delete_user") mock_two_squares_to_lan = mocker.patch( "chess_server.main.two_squares_and_piece_to_lan", return_value=move_lan, ) mock_get_result = mocker.patch( "chess_server.main.get_result_comment", side_effect=[self.result_unfinished, self.result_lose], ) mock_play_lan = mocker.patch("chess_server.main.Mediator.play_lan") mock_play_engine = mocker.patch( "chess_server.main.Mediator.play_engine_move_and_get_speech", return_value=self.engine_reply, ) mock_get_response = mocker.patch( "chess_server.main.get_response_for_google", return_value=self.result, ) mock_save_board_image = mocker.patch( "chess_server.main.save_board_as_png_and_get_image_card", return_value=self.card, ) req_data = get_dummy_webhook_request_for_google( session_id=self.session_id, action="two_squares", intent="two_squares", queryText="Pawn from e2 to e4", parameters=params, ) value = two_squares(req_data) assert value == self.result mock_get_user.assert_called_with(self.session_id) mock_del_user.assert_called_with(self.session_id) mock_two_squares_to_lan.assert_called_with(board=user.board, squares=squares, piece=piece) mock_get_result.assert_called_with(user=user) mock_play_lan.assert_called_with(session_id=self.session_id, lan=move_lan) mock_play_engine.assert_called_with(self.session_id) mock_save_board_image.assert_called_with(self.session_id) mock_get_response.assert_called_with( textToSpeech=f"spam ham and eggs. {self.result_lose}", expectUserResponse=False, basicCard=self.card, )
def test_get_result_comment_drawn_by_threefold_repetition(self): expected = RESPONSES["result_draw"].format( reason="threefold repetition") # As white board = chess.Board() user = User(board=board, color=chess.WHITE) self.assertEqual(get_result_comment(user=user), None) board.push_san("Nf3") board.push_san("Nf6") self.assertEqual(get_result_comment(user=user), None) board.push_san("Ng1") board.push_san("Ng8") self.assertEqual(get_result_comment(user=user), None) board.push_san("Nf3") board.push_san("Nf6") self.assertEqual(get_result_comment(user=user), None) board.push_san("Ng1") result = get_result_comment(user=user) self.assertEqual(result, expected) # As black board = chess.Board() user = User(board=board, color=chess.BLACK) board.push_san("Nf3") self.assertEqual(get_result_comment(user=user), None) board.push_san("Nf6") board.push_san("Ng1") self.assertEqual(get_result_comment(user=user), None) board.push_san("Ng8") board.push_san("Nf3") self.assertEqual(get_result_comment(user=user), None) board.push_san("Nf6") board.push_san("Ng1") result = get_result_comment(user=user) self.assertEqual(result, expected)
def test_get_result_comment_user_wins_as_white(self): user = User( board=chess.Board("4N3/ppp3Qk/2p5/7p/3P3P/8/P4P2/5K2 b - - 0 36"), color=chess.WHITE, ) expected = RESPONSES["result_win"] result = get_result_comment(user=user) self.assertEqual(result, expected)
def test_castle_game_ends_after_engine_move(self, mocker): user = User(board=chess.Board(), color=chess.BLACK) queryText = "castle" move_lan = "O-O" mock_get_user = mocker.patch("chess_server.main.get_user", return_value=user) mock_del_user = mocker.patch("chess_server.main.delete_user") mock_process_castle = mocker.patch( "chess_server.main.process_castle_by_querytext", return_value=move_lan, ) mock_get_result = mocker.patch( "chess_server.main.get_result_comment", side_effect=[self.result_unfinished, self.result_lose], ) mock_play_lan = mocker.patch("chess_server.main.Mediator.play_lan") mock_play_engine = mocker.patch( "chess_server.main.Mediator.play_engine_move_and_get_speech", return_value=self.engine_reply, ) mock_get_response = mocker.patch( "chess_server.main.get_response_for_google", return_value=self.result, ) mock_save_board_image = mocker.patch( "chess_server.main.save_board_as_png_and_get_image_card", return_value=self.card, ) req_data = get_dummy_webhook_request_for_google( session_id=self.session_id, action="castle", intent="castle", queryText=queryText, parameters={}, ) value = castle(req_data) assert value == self.result mock_get_user.assert_called_with(self.session_id) mock_del_user.assert_called_with(self.session_id) mock_process_castle.assert_called_with(board=user.board, queryText=queryText) mock_get_result.assert_called_with(user=user) mock_play_lan.assert_called_with(session_id=self.session_id, lan=move_lan) mock_play_engine.assert_called_with(self.session_id) mock_save_board_image.assert_called_with(self.session_id) mock_get_response.assert_called_with( textToSpeech=f"spam ham and eggs. {self.result_lose}", expectUserResponse=False, basicCard=self.card, )
def test_get_result_comment_drawn_by_stalemate(self): expected = RESPONSES["result_draw"].format(reason="stalemate") # As white user = User( board=chess.Board("7K/7P/7k/8/6q1/8/8/8 w - - 0 1"), color=chess.WHITE, ) result = get_result_comment(user=user) self.assertEqual(result, expected) # As black user = User( board=chess.Board("7K/7P/7k/8/6q1/8/8/8 w - - 0 1"), color=chess.BLACK, ) result = get_result_comment(user=user) self.assertEqual(result, expected)
def test_get_result_comment_drawn_by_fifty_move_rule(self): expected = RESPONSES["result_draw"].format(reason="fifty move rule") # As white user = User( board=chess.Board("4k3/8/6r1/8/8/8/2R5/4K3 w - - 120 1"), color=chess.WHITE, ) result = get_result_comment(user=user) self.assertEqual(result, expected) # As black user = User( board=chess.Board("4k3/8/6r1/8/8/8/2R5/4K3 w - - 120 1"), color=chess.BLACK, ) result = get_result_comment(user=user) self.assertEqual(result, expected)
def test_get_result_comment_drawn_by_insufficient_material(self): expected = RESPONSES["result_draw"].format( reason="insufficient material") # As white user = User( board=chess.Board("4k3/8/8/8/8/5B2/8/4K3 w - - 0 1"), color=chess.WHITE, ) result = get_result_comment(user=user) self.assertEqual(result, expected) # As black user = User( board=chess.Board("4k3/8/8/8/8/5B2/8/4K3 w - - 0 1"), color=chess.BLACK, ) result = get_result_comment(user=user) self.assertEqual(result, expected)
def test_get_result_comment_user_wins_as_black(self): user = User( board=chess.Board( "rnb1kbnr/pppp1ppp/8/4p3/6Pq/5P2/PPPPP2P/RNBQKBNR w KQkq - 1 3" ), color=chess.BLACK, ) expected = RESPONSES["result_win"] result = get_result_comment(user=user) self.assertEqual(result, expected)
def test_update_user(context): session_id = get_random_session_id() board = chess.Board() color = chess.BLACK create_user(session_id, board, color) # Now update it with some moves board.push_san("Nf3") board.push_san("d5") update_user(session_id, board) assert get_user(session_id) == User(board, color)
def test_update_user_multiple_entries(context): session_id = get_random_session_id() board = chess.Board() color = chess.WHITE create_user(session_id, board, color) # Create second user session_id2 = get_random_session_id() board2 = chess.Board() color2 = chess.BLACK board2.push_san("e4") board2.push_san("e5") create_user(session_id2, board2, color2) board.push_san("g4") update_user(session_id, board) assert get_user(session_id) == User(board, color) # Ensure that other entry has not been modified assert get_user(session_id2) == User(board2, color2)
def test_two_squares_uppercase(self, mocker): user = User(board=chess.Board(), color=chess.WHITE) squares = ["D2", "D4"] actual_squares = ["d2", "d4"] piece = "" move_lan = "d2-d4" params = {"squares": squares, "piece": piece} mock_get_user = mocker.patch("chess_server.main.get_user", return_value=user) mock_del_user = mocker.patch("chess_server.main.delete_user") mock_two_squares_to_lan = mocker.patch( "chess_server.main.two_squares_and_piece_to_lan", return_value=move_lan, ) mock_get_result = mocker.patch( "chess_server.main.get_result_comment", return_value=self.result_unfinished, ) mock_play_lan = mocker.patch("chess_server.main.Mediator.play_lan") mock_play_engine = mocker.patch( "chess_server.main.Mediator.play_engine_move_and_get_speech", return_value=self.engine_reply, ) mock_get_response = mocker.patch( "chess_server.main.get_response_for_google", return_value=self.result, ) req_data = get_dummy_webhook_request_for_google( session_id=self.session_id, action="two_squares", intent="two_squares", queryText="Pawn from D2 to D4", parameters=params, ) value = two_squares(req_data) assert value == self.result mock_get_user.assert_called_with(self.session_id) mock_del_user.assert_not_called() mock_two_squares_to_lan.assert_called_with(board=user.board, squares=actual_squares, piece=piece) mock_get_result.assert_called() mock_play_lan.assert_called_with(session_id=self.session_id, lan=move_lan) mock_play_engine.assert_called_with(self.session_id) assert mock_get_response.call_args[1]["textToSpeech"].startswith( self.engine_reply)
def test_get_result_comment_game_is_not_over_as_black(self): # Reference game: Morphy-Maurian, 1869 user = User( board=chess.Board( "r1bq2k1/ppp2Bp1/2np1n1p/b3p3/3PP3/B1P5/P4PPP/RN1Q1RK1 b - - " "0 11"), color=chess.BLACK, ) expected = None result = get_result_comment(user=user) self.assertEqual(result, expected)
def setUp(self): self.mock_engine_path = "engine_path" self.mock_engine = mock.MagicMock() self.board = chess.Board() self.color = chess.WHITE self.user = User(self.board, self.color) self.mediator = Mediator() # Mock the popen_uci method to return our mock engine self.patcher = mock.patch( "chess.engine.SimpleEngine.popen_uci", return_value=self.mock_engine, ) self.mock_popen_uci = self.patcher.start()
def test_castle_game_does_not_end(self, mocker): user = User(board=chess.Board(), color=chess.BLACK) queryText = "Castle short" move_lan = "O-O" mock_get_user = mocker.patch("chess_server.main.get_user", return_value=user) mock_del_user = mocker.patch("chess_server.main.delete_user") mock_process_castle = mocker.patch( "chess_server.main.process_castle_by_querytext", return_value=move_lan, ) mock_get_result = mocker.patch( "chess_server.main.get_result_comment", return_value=self.result_unfinished, ) mock_play_lan = mocker.patch("chess_server.main.Mediator.play_lan") mock_play_engine = mocker.patch( "chess_server.main.Mediator.play_engine_move_and_get_speech", return_value=self.engine_reply, ) mock_get_response = mocker.patch( "chess_server.main.get_response_for_google", return_value=self.result, ) req_data = get_dummy_webhook_request_for_google( session_id=self.session_id, action="castle", intent="castle", queryText=queryText, parameters={}, ) value = castle(req_data) assert value == self.result mock_get_user.assert_called_with(self.session_id) mock_del_user.assert_not_called() mock_process_castle.assert_called_with(board=user.board, queryText=queryText) mock_get_result.assert_called() mock_play_lan.assert_called_with(session_id=self.session_id, lan=move_lan) mock_play_engine.assert_called_with(self.session_id) assert mock_get_response.call_args[1]["textToSpeech"].startswith( self.engine_reply)
def test_delete_user(context): session_id = get_random_session_id() board = chess.Board() color = chess.BLACK create_user(session_id, board, color) # Verify that the user has been created assert get_user(session_id) == User(board, color) delete_user(session_id) # Verify that deletion is successful assert exists_in_db(session_id) is False # Verify that no other operation has been performed assert UserModel.query.count() == 0
def test_get_user_when_multiple_entries_exist(context): session_id = get_random_session_id() board = chess.Board() color = chess.WHITE # Make some moves board.push_san("Nc3") board.push_san("d5") board.push_san("d4") create_user(session_id, board, color) # Another entry session_id2 = get_random_session_id() board2 = chess.Board() color2 = chess.WHITE create_user(session_id2, board2, color2) assert get_user(session_id) == User(board, color)
def test_simply_san_invalid_move(self, mocker): fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1" user = User(board=chess.Board(fen), color=chess.WHITE) san = "Ki4+" mocker.patch("chess_server.main.get_user", return_value=user) mock_play_lan = mocker.patch("chess_server.main.Mediator.play_lan") mock_get_response = mocker.patch( "chess_server.main.get_response_for_google", return_value=self.result, ) req_data = get_dummy_webhook_request_for_google( session_id=self.session_id, action="simply_san", intent="simply_san", queryText=san, parameters={"san": san}, ) value = simply_san(req_data) assert value == self.result assert "not valid" in mock_get_response.call_args[1]["textToSpeech"] mock_play_lan.assert_not_called()