import { describe, it, expect, beforeAll, afterAll } from "vitest"; import { startTestServer, createBoard, join, type TestServer } from "./helpers.js"; let server: TestServer; beforeAll(async () => { server = await startTestServer(); }); afterAll(async () => { await server.close(); }); describe("Moderación y opciones", () => { it("por defecto cualquiera modera; al reclamar solo el reclamante", async () => { const board = await createBoard(server.url); const alice = await join(server.url, board.boardId, "alice", "Alice"); const bob = await join(server.url, board.boardId, "bob", "Bob"); // modo abierto por defecto expect(alice.last!.moderationMode).toBe("everyone"); // Alice reclama (sin token, permitido en modo abierto) y recibe un token nuevo const claimed = new Promise((resolve) => alice.socket.once("board:claimed", (p: { moderatorToken: string }) => resolve(p.moderatorToken)), ); alice.emit("board:claim", {}); const token = await claimed; await alice.waitFor((s) => s.moderationMode === "single"); // Bob (sin token) ya no puede revelar; Alice con su token sí bob.emit("board:reveal", { revealed: true }); await new Promise((r) => setTimeout(r, 150)); expect(bob.last!.revealed).toBe(false); alice.emit("board:reveal", { revealed: true, moderatorToken: token }); const revealed = await alice.waitFor((s) => s.revealed === true); expect(revealed.revealed).toBe(true); alice.close(); bob.close(); }); it("bloquear deja el board en solo lectura (no se añaden notas)", async () => { const board = await createBoard(server.url); const alice = await join(server.url, board.boardId, "alice", "Alice"); const colId = alice.last!.columns[0].id; alice.emit("board:update", { locked: true }); // modo abierto: cualquiera modera await alice.waitFor((s) => s.locked === true); alice.emit("note:add", { columnId: colId, text: "no debería entrar" }); await new Promise((r) => setTimeout(r, 200)); expect(alice.last!.notes).toHaveLength(0); // desbloquear y ahora sí alice.emit("board:update", { locked: false }); await alice.waitFor((s) => s.locked === false); alice.emit("note:add", { columnId: colId, text: "ahora sí" }); const after = await alice.waitFor((s) => s.notes.length === 1); expect(after.notes[0].text).toBe("ahora sí"); alice.close(); }); it("votes:clear borra todos los votos", async () => { const board = await createBoard(server.url); const alice = await join(server.url, board.boardId, "alice", "Alice"); const colId = alice.last!.columns[0].id; alice.emit("note:add", { columnId: colId, text: "x" }); const noteId = (await alice.waitFor((s) => s.notes.length === 1)).notes[0].id; alice.emit("vote:add", { targetType: "note", targetId: noteId }); await alice.waitFor((s) => s.votes.length === 1); alice.emit("votes:clear", {}); const cleared = await alice.waitFor((s) => s.votes.length === 0); expect(cleared.votes).toHaveLength(0); alice.close(); }); it("participant:rename actualiza la autoría de mis notas", async () => { const board = await createBoard(server.url); const alice = await join(server.url, board.boardId, "alice", "Alice"); const colId = alice.last!.columns[0].id; alice.emit("note:add", { columnId: colId, text: "mía" }); await alice.waitFor((s) => s.notes.length === 1 && s.notes[0].authorName === "Alice"); alice.emit("participant:rename", { name: "Alicia" }); const renamed = await alice.waitFor((s) => s.notes[0]?.authorName === "Alicia"); expect(renamed.notes[0].authorName).toBe("Alicia"); expect(renamed.participants.find((p) => p.id === "alice")?.name).toBe("Alicia"); alice.close(); }); it("la presencia lista a los participantes conectados", async () => { const board = await createBoard(server.url); const alice = await join(server.url, board.boardId, "alice", "Alice"); const bob = await join(server.url, board.boardId, "bob", "Bob"); const st = await alice.waitFor((s) => s.participants.length === 2); expect(st.participants.map((p) => p.name).sort()).toEqual(["Alice", "Bob"]); alice.close(); bob.close(); }); it("action item: marcar hecho", async () => { const board = await createBoard(server.url); const alice = await join(server.url, board.boardId, "alice", "Alice"); alice.emit("actionitem:add", { text: "documentar" }); const withItem = await alice.waitFor((s) => s.actionItems.length === 1); const id = withItem.actionItems[0].id; expect(withItem.actionItems[0].done).toBe(false); alice.emit("actionitem:toggle", { id, done: true }); const done = await alice.waitFor((s) => s.actionItems[0]?.done === true); expect(done.actionItems[0].done).toBe(true); alice.close(); }); });