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_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_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_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_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_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_webhook_unknown_intent(self, client, mocker): req_data = get_dummy_webhook_request_for_google(action="unknown") resp = client.post("/webhook", json=req_data) assert resp.status_code == 400 assert "Unknown intent action: unknown" in str(resp.get_data())
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_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_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_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_webhook_undo(self, client, mocker): mock_undo = mocker.patch("chess_server.routes.undo", return_value=self.result) req_data = get_dummy_webhook_request_for_google(action="undo") resp = client.post("/webhook", json=req_data) assert resp.get_json() == self.result mock_undo.assert_called_with(req_data)
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_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_welcome_color_is_given(self, context, mocker): mock_start_game = mocker.patch( "chess_server.main.start_game_and_get_response", return_value=self.result, ) color = "white" req_data = get_dummy_webhook_request_for_google( session_id=self.session_id, action="welcome", parameters={"color": color}, ) value = welcome(req_data) assert value == self.result mock_start_game.assert_called_once_with(self.session_id, color)
def test_show_board_success(self, client, config, mocker): mock_save_board_and_get_card = mocker.patch( "chess_server.main.save_board_as_png_and_get_image_card", return_value=self.card, ) 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="show_board") value = show_board(req_data) assert value == self.result mock_save_board_and_get_card.assert_called_with(self.session_id) assert mock_get_response.call_args[1]["basicCard"] == self.card
def test_undo_on_move_one(self, client): board = chess.Board() color = chess.BLACK board.push_san("e4") fen = board.fen() create_user(self.session_id, board, color) expected_text = "Nothing to undo!" req_data = get_dummy_webhook_request_for_google( session_id=self.session_id, action="undo", intent="undo") r = client.post(url_for("webhook_bp.webhook"), json=req_data) resp = GoogleWebhookResponse(r.json) assert get_user(self.session_id).board.fen() == fen assert expected_text in resp.simple_response.text_to_speech assert expected_text in resp.simple_response.display_text
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_choose_color(self, mocker): mock_start_game = mocker.patch( "chess_server.main.start_game_and_get_response", return_value=self.result, ) chosen_key = "chosen_key" req_data = get_dummy_webhook_request_for_google( session_id=self.session_id, action="choose_color", intent="choose_color", queryText="actions_intent_OPTION", option=("chosen_key", "title of that key"), ) value = choose_color(req_data) assert value == self.result mock_start_game.assert_called_with(self.session_id, chosen_key)
def test_welcome_color_is_not_given(self, context, mocker): 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="welcome", parameters={"color": ""}, ) value = welcome(req_data) assert value == self.result mock_get_response.assert_called() options = GoogleOptionsList(mock_get_response.call_args[1]["options"]) for key in ("white", "black", "random"): assert hasattr(options, key)
def test_undo_game_ended_after_users_move(self, client): board = chess.Board() color = chess.WHITE for san in ["e4", "e5", "Qh5", "Nc6", "Bc4", "Nf6"]: board.push_san(san) fen = board.fen() board.push_san("Qxf7#") undone_move = "Qxf7#" create_user(self.session_id, board, color) expected_text = f"OK! Undid the move {undone_move}" req_data = get_dummy_webhook_request_for_google( session_id=self.session_id, action="undo", intent="undo") r = client.post(url_for("webhook_bp.webhook"), json=req_data) resp = GoogleWebhookResponse(r.json) assert get_user(self.session_id).board.fen() == fen assert expected_text in resp.simple_response.text_to_speech assert expected_text in resp.simple_response.display_text
def test_resign(self, context, mocker): mock_del_user = mocker.patch("chess_server.main.delete_user") mock_get_response = mocker.patch( "chess_server.main.get_response_for_google", return_value=self.result, ) mocker.patch("chess_server.main.get_user", return_value=self.user) 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="resign", intent="resign") value = resign(req_data) assert value == self.result mock_del_user.assert_called_with(self.session_id) mock_save_board_image.assert_called_with(self.session_id) mock_get_response.assert_called_with( textToSpeech=mocker.ANY, expectUserResponse=False, basicCard=self.card, )
def test_undo(self, client): board = chess.Board() color = chess.BLACK for san in ["e4", "e5", "Nf3", "Nc6", "Bc4"]: board.push_san(san) fen = board.fen() board.push_san("Bc5") board.push_san("b4") engine_move, user_move = "b4", "Bc5" create_user(self.session_id, board, color) expected_text = ( f"Alright! The moves {user_move} and {engine_move} have been " "undone.") req_data = get_dummy_webhook_request_for_google( session_id=self.session_id, action="undo", intent="undo") r = client.post(url_for("webhook_bp.webhook"), json=req_data) resp = GoogleWebhookResponse(r.json) assert get_user(self.session_id).board.fen() == fen assert expected_text in resp.simple_response.text_to_speech assert expected_text in resp.simple_response.display_text
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()