add a test with 2 players
authorLaurent Mazet <mazet@softndesign.org>
Fri, 24 Jul 2026 10:22:13 +0000 (12:22 +0200)
committerLaurent Mazet <mazet@softndesign.org>
Tue, 11 Aug 2026 20:26:55 +0000 (22:26 +0200)
test/test-state.js

index c89959752fafea7ceaf055c32e59bb0fcc7bbcb2..53acacd6f9e8038decd75dae7b855a1ddccf89b4 100644 (file)
@@ -113,6 +113,50 @@ async function testSetRackValidation() {
     assert(body[0].reason === "the new rack is not at the right size", "oversized rack should explain size mismatch");
 }
 
+/* A new player can join a game that already has state and players. */
+async function testSecondPlayerJoinsStartedGame() {
+    const firstPlayer = randomPlayer("started-a");
+    const secondPlayer = randomPlayer("started-b");
+
+    const join = await postJson({playerName: firstPlayer, cmds: [{cmd: "joinGame"}]});
+    const joinBody = JSON.parse(join.body);
+    const gameNumber = joinBody[0].gameNumber;
+
+    await postJson({
+        playerName: firstPlayer,
+        gameNumber,
+        cmds: [{cmd: "moveLetter", from: "bag", to: "rack", indexTo: 0}]
+    });
+
+    await postJson({
+        playerName: firstPlayer,
+        gameNumber,
+        cmds: [{cmd: "moveLetter", from: "rack", indexFrom: 0, to: "board", indexTo: 0}]
+    });
+
+    await postJson({
+        playerName: firstPlayer,
+        gameNumber,
+        cmds: [{cmd: "score", player: firstPlayer, score: 17}]
+    });
+
+    const secondJoin = await postJson({playerName: secondPlayer, gameNumber, cmds: [{cmd: "joinGame"}]});
+    const secondJoinBody = JSON.parse(secondJoin.body);
+    const state = secondJoinBody[0];
+
+    assert(state.error === 0, "second player joinGame should succeed on an existing game");
+    assert(state.gameNumber === gameNumber, "second player should join the existing game number");
+    assert(Array.isArray(state.rack), "second player should receive a rack array");
+    assert(Array.isArray(state.board), "second player should receive the current board");
+    assert(state.board[0] !== "", "second player should see letters already placed on the board");
+    assert(state.remainingLetters >= 0, "second player should receive the remaining bag size");
+    assert(state.chatHistory !== undefined, "second player should receive chat history information");
+
+    const firstPlayerState = await postJson({playerName: firstPlayer, gameNumber, cmds: [{cmd: "joinGame"}]});
+    const firstPlayerStateBody = JSON.parse(firstPlayerState.body)[0];
+    assert(firstPlayerStateBody.board[0] === state.board[0], "existing board state should be shared across players");
+}
+
 /* A player can leave and later rejoin the same game. */
 async function testLeaveGameRemovesPlayer() {
     const gameNumber = `leave-${Date.now()}-${Math.floor(Math.random() * 1e6)}`;
@@ -312,6 +356,7 @@ runTestSection("STATE", [
     testMoveValidation,
     testChangePlayerNameValidation,
     testSetRackValidation,
+    testSecondPlayerJoinsStartedGame,
     testLeaveGameRemovesPlayer,
     testChatTruncation,
     testChatHistoryRollsOver,