import assert from "node:assert/strict"; import { test } from "node:test"; import { createRoomSchema, joinRoomSchema, roomGuessSchema, chatMessageSchema, } from "../shared/multiplayer"; const map = "00000000-0000-4000-8000-000000000000"; test("chat accepts plain multilingual text and rejects blank, oversized or hidden-control messages", () => { assert.equal( chatMessageSchema.parse({ clientId: map, text: " Привет (: " }).text, "Привет (:", ); assert.equal( chatMessageSchema.safeParse({ clientId: map, text: "x".repeat(500) }) .success, true, ); for (const text of [ "", " ", "x".repeat(501), "hidden\u202e", "hidden\u0085", "x\nname", "x\u0000name", ]) assert.equal( chatMessageSchema.safeParse({ clientId: map, text }).success, false, ); assert.equal( chatMessageSchema.safeParse({ clientId: "wrong", text: "hi" }).success, false, ); assert.equal( chatMessageSchema.parse({ clientId: map, text: "", }).text, "", ); }); test("room limits include the owner and stay between 2 and 16", () => { for (const playerLimit of [2, 16]) assert.equal( createRoomSchema.parse({ datasetId: map, difficulty: "normal", displayName: " Alex ", playerLimit, }).displayName, "Alex", ); for (const playerLimit of [1, 17, 2.5, "16", null]) assert.equal( createRoomSchema.safeParse({ datasetId: map, difficulty: "normal", displayName: "Alex", playerLimit, }).success, false, ); }); test("multiplayer names and guesses reject hidden controls, invalid rounds, and non-finite positions", () => { assert.equal( joinRoomSchema.parse({ displayName: " Друг " }).displayName, "Друг", ); for (const displayName of ["a", "x\nname", "name\u202e", "a".repeat(33)]) assert.equal(joinRoomSchema.safeParse({ displayName }).success, false); for (const payload of [ { round: 5, x: 0, z: 0 }, { round: 0, x: Infinity, z: 0 }, { round: 0, x: NaN, z: 0 }, { round: 0, x: 0 }, ]) assert.equal(roomGuessSchema.safeParse(payload).success, false); });