Files
CRAPP/test/unit/palloni-core.test.ts
T
davide 923d1fe762 Aggiorna i test per le nuove firme con rosa esplicita
completaTurni() e csvScoutMatch() prendono ora la rosa come parametro
invece di leggerla dalla lista statica di crapp-data.ts.
2026-09-03 10:17:07 +02:00

165 lines
5.9 KiB
TypeScript

/** Check dei turni palloni: `bun src/lib/palloni-core.test.ts`. */
import assert from "node:assert/strict";
import { formatData, giocatori } from "@/lib/crapp-data";
import type { Evento } from "@/lib/eventi";
import {
completaTurni,
conteggioTurni,
destinatariPromemoriaPalloni,
eventiDelGiorno,
eventiPalloni,
eventoPrecedente,
eventoSuccessivo,
messaggioPalloniOggi,
oggiISO,
} from "@/lib/palloni-core";
const rosa = giocatori.map((g) => ({ id: g.id, nome: g.nome }));
const evento = (id: string, data: string, tipo: Evento["tipo"] = "allenamento"): Evento => ({
id,
tipo,
titolo: `Evento ${id}`,
luogo: "PalaCRAP",
data,
ora: "21:00",
note: "",
convocati: [],
campionato: false,
casa: true,
pagelleChiuse: false,
});
const eventi: Evento[] = [
evento("e3", "2026-09-10"),
evento("e1", "2026-09-01"),
evento("compleanno", "2026-09-05", "compleanno"),
evento("e2", "2026-09-05", "partita"),
];
// --- eventiPalloni: ordina per data e scarta i compleanni ---------------------
const ordinati = eventiPalloni(eventi);
assert.deepEqual(
ordinati.map((e) => e.id),
["e1", "e2", "e3"],
"compleanni esclusi e ordine cronologico",
);
assert.equal(eventi[0]!.id, "e3", "l'array in ingresso non viene modificato");
// --- eventoPrecedente / eventoSuccessivo -------------------------------------
assert.equal(eventoPrecedente(eventi, "e2")?.id, "e1");
assert.equal(eventoPrecedente(eventi, "e1"), undefined, "il primo non ha precedente");
assert.equal(eventoSuccessivo(eventi, "e2")?.id, "e3");
assert.equal(eventoSuccessivo(eventi, "e3"), undefined, "l'ultimo non ha successivo");
assert.equal(eventoPrecedente(eventi, "inesistente"), undefined);
// --- eventiDelGiorno ---------------------------------------------------------
assert.deepEqual(
eventiDelGiorno(eventi, "2026-09-05").map((e) => e.id),
["e2"],
"il compleanno dello stesso giorno non richiede palloni",
);
// --- completaTurni: assegna i mancanti, rispetta quelli già decisi -----------
const turni = completaTurni({ e2: "g5" }, eventi, rosa);
assert.equal(turni["e2"], "g5", "il turno già assegnato non viene toccato");
assert.equal(Object.keys(turni).length, 3, "tutti gli eventi hanno un incaricato");
assert.ok(
giocatori.some((g) => g.id === turni["e1"]),
"assegna a un giocatore reale",
);
assert.notEqual(turni["e1"], turni["e3"], "non tocca due volte di fila alla stessa persona");
const molti = Array.from({ length: giocatori.length + 2 }, (_, i) =>
evento(`x${i}`, `2026-10-${String(i + 1).padStart(2, "0")}`),
);
const rotazione = conteggioTurni(completaTurni({}, molti, rosa));
const carichi = Object.values(rotazione);
assert.equal(
Math.max(...carichi) - Math.min(...carichi),
1,
"su un giro completo il carico resta bilanciato",
);
assert.equal(
Object.keys(rotazione).length,
giocatori.length,
"nessuno viene saltato prima che tutti abbiano fatto un turno",
);
// Un turno salvato per un giocatore non più in rosa non deve rompere il conteggio.
const conFantasma = completaTurni({ e1: "gXX" }, eventi, rosa);
assert.equal(conFantasma["e1"], "gXX", "il turno storico resta com'è");
assert.equal(Object.keys(conFantasma).length, 3);
// --- conteggioTurni ----------------------------------------------------------
assert.deepEqual(conteggioTurni({ a: "g1", b: "g1", c: "g2" }), { g1: 2, g2: 1 });
assert.deepEqual(conteggioTurni({}), {});
// --- oggiISO -----------------------------------------------------------------
assert.match(oggiISO(), /^\d{4}-\d{2}-\d{2}$/);
assert.equal(oggiISO(), new Date().toLocaleDateString("sv-SE"), "data locale, non UTC");
// --- destinatariPromemoriaPalloni --------------------------------------------
const eventiPush: Evento[] = [
evento("p1", "2026-02-01"),
evento("p2", "2026-02-02"),
evento("p3", "2026-02-03"),
];
const turniPush = { p1: "g1", p2: "g2", p3: "g3" };
assert.deepEqual(
destinatariPromemoriaPalloni(turniPush, eventiPush, "2026-02-02"),
["g2", "g1"],
"chi porta oggi e chi li aveva portati alla volta prima",
);
assert.deepEqual(
destinatariPromemoriaPalloni(turniPush, eventiPush, "2026-02-01"),
["g1"],
"il primo evento non ha un precedente da avvisare",
);
assert.deepEqual(
destinatariPromemoriaPalloni(turniPush, eventiPush, "2026-03-01"),
[],
"nessun evento in quella data: nessun destinatario",
);
assert.deepEqual(
destinatariPromemoriaPalloni({ p1: "g1", p2: "g1" }, eventiPush, "2026-02-02"),
["g1"],
"stessa persona oggi e alla volta prima: un solo avviso",
);
// --- messaggioPalloniOggi -----------------------------------------------------
assert.deepEqual(
messaggioPalloniOggi(turniPush, eventiPush, "2026-02-02", "g1", "Mario"),
{
title: "Porta i palloni oggi",
body: "Evento p2 · 21:00. I palloni li hai tu dalla volta scorsa.",
},
"chi li aveva alla volta prima deve riportarli oggi",
);
assert.deepEqual(
messaggioPalloniOggi(turniPush, eventiPush, "2026-02-02", "g2", "Luca"),
{
title: "Tocca a te prendere i palloni",
body: `A fine Evento p2 porta a casa i palloni e riportali il ${formatData("2026-02-03")}.`,
},
"l'incaricato di oggi sa quando riportarli, se c'è un evento successivo",
);
assert.deepEqual(
messaggioPalloniOggi(turniPush, eventiPush, "2026-02-03", "g3", "Anna"),
{ title: "Tocca a te prendere i palloni", body: "A fine Evento p3 porta a casa i palloni." },
"senza evento successivo il messaggio non promette una data",
);
assert.deepEqual(
messaggioPalloniOggi(turniPush, eventiPush, "2026-02-02", "g9", "Sara"),
{ title: "CrAPP · Turno palloni", body: "Sara, controlla il turno palloni nel calendario." },
"chi non è coinvolto oggi riceve il messaggio generico col proprio nome",
);
assert.deepEqual(
messaggioPalloniOggi(turniPush, eventiPush, "2026-05-01", "g9", ""),
{ title: "CrAPP · Turno palloni", body: "Controlla il calendario." },
"senza eventi in quella data e senza nome noto, il messaggio resta generico",
);
console.log("palloni-core: ok");