Servidor Fastify + Socket.IO + Drizzle/Postgres; front Vite+React (EN/ES, tema claro/oscuro). Tableros por columnas con plantillas, notas privadas/públicas, agrupación, votos configurables (multivoto), timer compartido con alarma, fases, action items, export Markdown/JSON e import, autodestrucción, gestión de columnas. Imagen única (front servido por el servidor) y CI que la construye y publica.
74 lines
2.9 KiB
TypeScript
74 lines
2.9 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();
|
|
});
|
|
|
|
async function twoNotes(boardId: string, url: string) {
|
|
const alice = await join(url, boardId, "alice", "Alice");
|
|
const colId = alice.last!.columns[0].id;
|
|
alice.emit("note:add", { columnId: colId, text: "A" });
|
|
alice.emit("note:add", { columnId: colId, text: "B" });
|
|
const st = await alice.waitFor((s) => s.notes.length === 2);
|
|
const [a, b] = st.notes;
|
|
return { alice, colId, a, b };
|
|
}
|
|
|
|
describe("Grupos", () => {
|
|
it("agrupar dos notas crea un grupo votable", async () => {
|
|
const board = await createBoard(server.url);
|
|
const { alice, a, b } = await twoNotes(board.boardId, server.url);
|
|
|
|
alice.emit("group:create", { noteId: b.id, targetNoteId: a.id });
|
|
const grouped = await alice.waitFor((s) => s.groups.length === 1);
|
|
const groupId = grouped.groups[0].id;
|
|
expect(grouped.notes.every((n) => n.groupId === groupId)).toBe(true);
|
|
|
|
// votar el grupo como unidad
|
|
alice.emit("vote:toggle", { targetType: "group", targetId: groupId });
|
|
const voted = await alice.waitFor((s) => s.votes.some((v) => v.targetId === groupId));
|
|
expect(voted.votes.filter((v) => v.targetId === groupId)).toHaveLength(1);
|
|
|
|
alice.close();
|
|
});
|
|
|
|
it("al agrupar se reinician los votos sueltos de las notas", async () => {
|
|
const board = await createBoard(server.url);
|
|
const { alice, a, b } = await twoNotes(board.boardId, server.url);
|
|
|
|
alice.emit("vote:toggle", { targetType: "note", targetId: a.id });
|
|
await alice.waitFor((s) => s.votes.some((v) => v.targetId === a.id));
|
|
|
|
alice.emit("group:create", { noteId: b.id, targetNoteId: a.id });
|
|
const after = await alice.waitFor((s) => s.groups.length === 1);
|
|
expect(after.votes.filter((v) => v.targetId === a.id)).toHaveLength(0);
|
|
|
|
alice.close();
|
|
});
|
|
|
|
it("sacar la última nota de un grupo lo elimina", async () => {
|
|
const board = await createBoard(server.url);
|
|
const { alice, colId, a, b } = await twoNotes(board.boardId, server.url);
|
|
|
|
alice.emit("group:create", { noteId: b.id, targetNoteId: a.id });
|
|
const grouped = await alice.waitFor((s) => s.groups.length === 1);
|
|
expect(grouped.groups).toHaveLength(1);
|
|
|
|
// saca una nota: el grupo sigue (1 miembro)
|
|
alice.emit("note:move", { noteId: a.id, columnId: colId, groupId: null, position: 5 });
|
|
await alice.waitFor((s) => s.notes.filter((n) => n.groupId).length === 1);
|
|
|
|
// saca la última: el grupo se borra
|
|
alice.emit("note:move", { noteId: b.id, columnId: colId, groupId: null, position: 6 });
|
|
const empty = await alice.waitFor((s) => s.groups.length === 0);
|
|
expect(empty.groups).toHaveLength(0);
|
|
|
|
alice.close();
|
|
});
|
|
});
|