Skip to content

Commit 20f82ff

Browse files
committed
refactor(tests): use helper function to assert error responses
1 parent 3039d63 commit 20f82ff

File tree

3 files changed

+36
-37
lines changed

3 files changed

+36
-37
lines changed

tests/conftest.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
# Connection settings
1010
HOST = "127.0.0.1"
1111
PORT: int = 12346 # default port for BalatroBot UDP API
12-
TIMEOUT: float = 30.0 # timeout for socket operations in seconds
12+
TIMEOUT: float = 10.0 # timeout for socket operations in seconds
1313
BUFFER_SIZE: int = 65536 # 64KB buffer for UDP messages
1414

1515

@@ -68,3 +68,15 @@ def send_and_receive_api_message(
6868
send_api_message(sock, name, arguments)
6969
game_state = receive_api_message(sock)
7070
return game_state
71+
72+
73+
def assert_error_response(response, expected_error_text, expected_context_keys=None):
74+
"""Helper function to assert error response format and content."""
75+
assert isinstance(response, dict)
76+
assert "error" in response
77+
assert "state" in response
78+
assert expected_error_text in response["error"]
79+
if expected_context_keys:
80+
assert "context" in response
81+
for key in expected_context_keys:
82+
assert key in response["context"]

tests/test_api_functions.py

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from typing import Generator
55

66
import pytest
7-
from conftest import send_and_receive_api_message
7+
from conftest import send_and_receive_api_message, assert_error_response
88

99
from balatrobot.enums import State
1010

@@ -127,9 +127,7 @@ def test_start_run_missing_required_args(self, udp_client: socket.socket) -> Non
127127
response = send_and_receive_api_message(
128128
udp_client, "start_run", incomplete_args
129129
)
130-
assert isinstance(response, dict)
131-
assert "error" in response
132-
assert "Invalid deck arg" in response["error"]
130+
assert_error_response(response, "Invalid deck arg for start_run")
133131

134132
def test_start_run_invalid_deck(self, udp_client: socket.socket) -> None:
135133
"""Test start_run with invalid deck name."""
@@ -141,9 +139,7 @@ def test_start_run_invalid_deck(self, udp_client: socket.socket) -> None:
141139
}
142140
# Should receive error response
143141
response = send_and_receive_api_message(udp_client, "start_run", invalid_args)
144-
assert isinstance(response, dict)
145-
assert "error" in response
146-
assert "Invalid deck arg" in response["error"]
142+
assert_error_response(response, "Invalid deck arg for start_run", ["deck"])
147143

148144

149145
class TestGoToMenu:
@@ -231,9 +227,9 @@ def test_invalid_blind_action(self, udp_client: socket.socket) -> None:
231227
)
232228

233229
# Verify error response
234-
assert isinstance(error_response, dict)
235-
assert "error" in error_response
236-
assert "Invalid action arg" in error_response["error"]
230+
assert_error_response(
231+
error_response, "Invalid action arg for skip_or_select_blind", ["action"]
232+
)
237233

238234

239235
class TestPlayHandOrDiscard:
@@ -327,9 +323,9 @@ def test_play_hand_or_discard_invalid_cards(
327323
)
328324

329325
# Should receive error response for invalid card index
330-
assert isinstance(response, dict)
331-
assert "error" in response
332-
assert "Invalid card index" in response["error"]
326+
assert_error_response(
327+
response, "Invalid card index", ["card_index", "hand_size"]
328+
)
333329

334330
def test_play_hand_invalid_action(self, udp_client: socket.socket) -> None:
335331
"""Test playing a hand with invalid action returns error."""
@@ -339,9 +335,9 @@ def test_play_hand_invalid_action(self, udp_client: socket.socket) -> None:
339335
)
340336

341337
# Should receive error response for invalid action
342-
assert isinstance(response, dict)
343-
assert "error" in response
344-
assert "Invalid action arg" in response["error"]
338+
assert_error_response(
339+
response, "Invalid action arg for play_hand_or_discard", ["action"]
340+
)
345341

346342
@pytest.mark.parametrize(
347343
"cards,expected_new_cards",
@@ -407,9 +403,9 @@ def test_try_to_discard_when_no_discards_left(
407403
)
408404

409405
# Should receive error response for no discards left
410-
assert isinstance(response, dict)
411-
assert "error" in response
412-
assert "No discards left" in response["error"]
406+
assert_error_response(
407+
response, "No discards left to perform discard", ["discards_left"]
408+
)
413409

414410

415411
class TestCashOut:
@@ -461,7 +457,6 @@ def test_cash_out_invalid_state_error(self, udp_client: socket.socket) -> None:
461457
response = send_and_receive_api_message(udp_client, "cash_out", {})
462458

463459
# Verify error response
464-
assert isinstance(response, dict)
465-
assert "error" in response
466-
assert "Cannot cash out when not in shop" in response["error"]
467-
assert "state" in response
460+
assert_error_response(
461+
response, "Cannot cash out when not in shop", ["current_state"]
462+
)

tests/test_connection.py

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import socket
55

66
import pytest
7-
from conftest import BUFFER_SIZE, HOST, PORT, send_api_message
7+
from conftest import BUFFER_SIZE, HOST, PORT, send_api_message, assert_error_response
88

99

1010
def test_basic_connection(udp_client: socket.socket) -> None:
@@ -54,9 +54,7 @@ def test_invalid_json_message(udp_client: socket.socket) -> None:
5454
data, _ = udp_client.recvfrom(BUFFER_SIZE)
5555
response = data.decode().strip()
5656
error_response = json.loads(response)
57-
assert isinstance(error_response, dict)
58-
assert "error" in error_response
59-
assert "Invalid JSON" in error_response["error"]
57+
assert_error_response(error_response, "Invalid JSON")
6058

6159
# Verify server is still responsive
6260
send_api_message(udp_client, "get_game_state", {})
@@ -77,9 +75,7 @@ def test_missing_name_field(udp_client: socket.socket) -> None:
7775
data, _ = udp_client.recvfrom(BUFFER_SIZE)
7876
response = data.decode().strip()
7977
error_response = json.loads(response)
80-
assert isinstance(error_response, dict)
81-
assert "error" in error_response
82-
assert "Message must contain a name" in error_response["error"]
78+
assert_error_response(error_response, "Message must contain a name")
8379

8480
# Verify server is still responsive
8581
send_api_message(udp_client, "get_game_state", {})
@@ -100,9 +96,7 @@ def test_missing_arguments_field(udp_client: socket.socket) -> None:
10096
data, _ = udp_client.recvfrom(BUFFER_SIZE)
10197
response = data.decode().strip()
10298
error_response = json.loads(response)
103-
assert isinstance(error_response, dict)
104-
assert "error" in error_response
105-
assert "Message must contain arguments" in error_response["error"]
99+
assert_error_response(error_response, "Message must contain arguments")
106100

107101
# Verify server is still responsive
108102
send_api_message(udp_client, "get_game_state", {})
@@ -123,9 +117,7 @@ def test_unknown_message(udp_client: socket.socket) -> None:
123117
data, _ = udp_client.recvfrom(BUFFER_SIZE)
124118
response = data.decode().strip()
125119
error_response = json.loads(response)
126-
assert isinstance(error_response, dict)
127-
assert "error" in error_response
128-
assert "Unknown function name" in error_response["error"]
120+
assert_error_response(error_response, "Unknown function name", ["function_name"])
129121

130122
# Verify server is still responsive
131123
send_api_message(udp_client, "get_game_state", {})

0 commit comments

Comments
 (0)