File size: 3,416 Bytes
4be6a52 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | from fastapi.testclient import TestClient
from stackcraft.server import create_app
def test_game_action_replay_round_trip():
with TestClient(create_app()) as client:
first = client.post("/api/games", json={"seed": 42}).json()
other = client.post("/api/games", json={"seed": 42}).json()
assert first["board"] == other["board"]
assert first["current"] == other["current"]
assert "seed" not in first
game_id = first["id"]
result = client.post(
f"/api/games/{game_id}/moves",
json={"action_id": first["legal_actions"][0]["id"], "expected_pieces": 0},
)
assert result.status_code == 200
assert result.json()["pieces"] == 1
assert client.get(f"/api/games/{other['id']}").json()["pieces"] == 0
replay = client.get(f"/api/games/{game_id}/replay").json()
restored = client.post("/api/replays", json=replay)
assert restored.status_code == 200
frames = restored.json()["frames"]
assert len(frames) == 2
assert frames[-1] == {k: v for k, v in result.json().items() if k != "id"}
def test_invalid_move_preserves_game_and_unknown_sessions_fail():
with TestClient(create_app()) as client:
original = client.post("/api/games", json={"seed": 7}).json()
path = f"/api/games/{original['id']}"
assert (
client.post(
path + "/moves", json={"action_id": "r9x99", "expected_pieces": 0}
).status_code
== 422
)
assert client.get(path).json() == original
assert client.get("/api/games/missing").status_code == 404
def test_retry_after_lost_response_cannot_place_another_piece():
with TestClient(create_app()) as client:
state = client.post("/api/games", json={"seed": 42}).json()
path = f"/api/games/{state['id']}"
request = {"action_id": "r0x3", "expected_pieces": 0}
accepted = client.post(path + "/moves", json=request)
assert accepted.status_code == 200
retry = client.post(path + "/moves", json=request)
assert retry.status_code == 409
assert client.get(path).json() == accepted.json()
def test_input_validation_and_health():
with TestClient(create_app()) as client:
assert client.get("/health").json() == {"status": "ok"}
for seed in [-1, True, "42", 2**53]:
assert client.post("/api/games", json={"seed": seed}).status_code == 422
assert client.post("/api/replays", json={"actions": "not a list"}).status_code == 422
assert client.post("/api/replays", json={"actions": ["r0x0"] * 2001}).status_code == 422
def test_packaged_race_replays_validate_against_current_engine():
with TestClient(create_app()) as client:
response = client.get("/static/baseline-demo.json")
assert response.status_code == 200
race = response.json()
assert [player["id"] for player in race["players"]] == ["base", "trained", "heuristic"]
for player in race["players"]:
assert player["replay"]["seed"] == race["seed"]
replay = client.post("/api/replays", json=player["replay"])
assert replay.status_code == 200
final = replay.json()["frames"][-1]
assert final["pieces"] <= race["max_pieces"]
assert final["score"] == player["replay"]["final"]["score"]
|