109 lines
4.2 KiB
TypeScript
109 lines
4.2 KiB
TypeScript
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("Socket.IO — flujo de retro", () => {
|
||
|
|
it("oculta las notas de otros hasta revelar", 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 colId = alice.last!.columns[0].id;
|
||
|
|
|
||
|
|
alice.emit("note:add", { columnId: colId, text: "secreto de Alice" });
|
||
|
|
|
||
|
|
const bobState = await bob.waitFor((s) => s.notes.length === 1);
|
||
|
|
expect(bobState.notes[0].text).toBe(""); // oculta para Bob
|
||
|
|
expect(bobState.notes[0].authorName).toBe("Alice");
|
||
|
|
|
||
|
|
const aliceState = await alice.waitFor((s) => s.notes.length === 1);
|
||
|
|
expect(aliceState.notes[0].text).toBe("secreto de Alice"); // visible para la autora
|
||
|
|
|
||
|
|
alice.close();
|
||
|
|
bob.close();
|
||
|
|
});
|
||
|
|
|
||
|
|
it("revela las notas a todos cuando el moderador lo pide", 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 colId = alice.last!.columns[0].id;
|
||
|
|
|
||
|
|
alice.emit("note:add", { columnId: colId, text: "visible tras revelar" });
|
||
|
|
await bob.waitFor((s) => s.notes.length === 1);
|
||
|
|
|
||
|
|
// Bob (sin token) no puede revelar; Alice (moderadora) sí
|
||
|
|
bob.emit("board:reveal", { revealed: true });
|
||
|
|
alice.emit("board:reveal", { revealed: true, moderatorToken: board.moderatorToken });
|
||
|
|
|
||
|
|
const revealed = await bob.waitFor((s) => s.revealed === true);
|
||
|
|
expect(revealed.notes[0].text).toBe("visible tras revelar");
|
||
|
|
|
||
|
|
alice.close();
|
||
|
|
bob.close();
|
||
|
|
});
|
||
|
|
|
||
|
|
it("respeta el límite de votos por persona", async () => {
|
||
|
|
const board = await createBoard(server.url, { votesPerUser: 2 });
|
||
|
|
const alice = await join(server.url, board.boardId, "alice", "Alice");
|
||
|
|
const colId = alice.last!.columns[0].id;
|
||
|
|
|
||
|
|
for (const txt of ["a", "b", "c"]) alice.emit("note:add", { columnId: colId, text: txt });
|
||
|
|
const withNotes = await alice.waitFor((s) => s.notes.length === 3);
|
||
|
|
const ids = withNotes.notes.map((n) => n.id);
|
||
|
|
const mine = (s: { votes: { participantId: string }[] }) =>
|
||
|
|
s.votes.filter((v) => v.participantId === "alice").length;
|
||
|
|
|
||
|
|
// vota las dos primeras (confirmando cada una)
|
||
|
|
alice.emit("vote:toggle", { noteId: ids[0] });
|
||
|
|
await alice.waitFor((s) => mine(s) === 1);
|
||
|
|
alice.emit("vote:toggle", { noteId: ids[1] });
|
||
|
|
await alice.waitFor((s) => mine(s) === 2);
|
||
|
|
|
||
|
|
// el tercer voto se rechaza (cupo = 2)
|
||
|
|
alice.emit("vote:toggle", { noteId: ids[2] });
|
||
|
|
await new Promise((r) => setTimeout(r, 200));
|
||
|
|
expect(mine(alice.last!)).toBe(2);
|
||
|
|
|
||
|
|
// quitar un voto libera cupo
|
||
|
|
alice.emit("vote:toggle", { noteId: ids[0] });
|
||
|
|
const afterUnvote = await alice.waitFor((s) => mine(s) === 1);
|
||
|
|
expect(afterUnvote.votes).toHaveLength(1);
|
||
|
|
|
||
|
|
alice.close();
|
||
|
|
});
|
||
|
|
|
||
|
|
it("comparte el timer (endsAt) con todos los participantes", 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");
|
||
|
|
|
||
|
|
alice.emit("timer:start", { seconds: 300, moderatorToken: board.moderatorToken });
|
||
|
|
const bobState = await bob.waitFor((s) => s.timerRunning);
|
||
|
|
expect(bobState.timerEndsAt).toBeTruthy();
|
||
|
|
expect(new Date(bobState.timerEndsAt!).getTime()).toBeGreaterThan(Date.now());
|
||
|
|
|
||
|
|
alice.close();
|
||
|
|
bob.close();
|
||
|
|
});
|
||
|
|
|
||
|
|
it("crea action items visibles para todos", 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");
|
||
|
|
|
||
|
|
alice.emit("actionitem:add", { text: "documentar el deploy" });
|
||
|
|
const bobState = await bob.waitFor((s) => s.actionItems.length === 1);
|
||
|
|
expect(bobState.actionItems[0].text).toBe("documentar el deploy");
|
||
|
|
|
||
|
|
alice.close();
|
||
|
|
bob.close();
|
||
|
|
});
|
||
|
|
});
|