Cappa le vittorie di "10 vittorie in campionato" e completa la copertura test
o5 non aveva il Math.min(vittorie, 10) dei fratelli o3/o4: il progresso mostrato non cambiava (già cappato al 100%), ma il valore grezzo sì, mostrato senza cap in squadra.tsx/index.tsx (es. "15/10 vittorie" invece di "10/10"). Nessuno dei tre obiettivi aveva test. Le vittorie non toccano Supabase - arrivano dal portale CSI via /api/public/csi - quindi l'integration test estende test/integration/api.test.ts (che già chiama quella route dal vivo) invece di test/integration/obiettivi.test.ts, verificando o3/o4/o5 sui dati CSI reali del giorno. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -170,7 +170,7 @@ export function obiettiviSquadra(
|
||||
id: "o5",
|
||||
titolo: "10 vittorie in campionato",
|
||||
descrizione: "Obiettivo stagionale per il podio",
|
||||
valore: vittorie,
|
||||
valore: Math.min(vittorie, 10),
|
||||
target: 10,
|
||||
unita: "vittorie",
|
||||
emoji: "🏆",
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
* Nessun test scrive sul database: solo letture e validazioni.
|
||||
*/
|
||||
import assert from "node:assert/strict";
|
||||
import { isNostraSquadra, type DatiCsi } from "@/lib/csi-core";
|
||||
import { giocatori } from "@/lib/crapp-data";
|
||||
import { isNostraSquadra, partiteGiocate, type DatiCsi } from "@/lib/csi-core";
|
||||
import { obiettiviSquadra } from "@/lib/obiettivi";
|
||||
import { avviaServer, haSupabase, json } from "../helpers/server";
|
||||
import { prova, riepilogo, salta } from "../helpers/prova";
|
||||
|
||||
@@ -58,6 +60,32 @@ try {
|
||||
}
|
||||
});
|
||||
|
||||
await prova(
|
||||
"le vittorie in campionato lette dal CSI reale alimentano o3/o4/o5 in modo coerente",
|
||||
() => {
|
||||
// Stessa logica di useObiettivi() in src/lib/rosa.ts: partite giocate e vinte.
|
||||
const vittorieReali = partiteGiocate(csi?.partite ?? []).filter(
|
||||
(p) => (p.setNostri ?? 0) > (p.setLoro ?? 0),
|
||||
).length;
|
||||
|
||||
const obiettivi = obiettiviSquadra(giocatori, {
|
||||
eventi: [],
|
||||
presenze: {},
|
||||
pagelle: [],
|
||||
vittorie: vittorieReali,
|
||||
});
|
||||
const o3 = obiettivi.find((o) => o.id === "o3")!;
|
||||
const o4 = obiettivi.find((o) => o.id === "o4")!;
|
||||
const o5 = obiettivi.find((o) => o.id === "o5")!;
|
||||
|
||||
assert.deepEqual([o3.target, o4.target, o5.target], [1, 5, 10], "target fissi 1/5/10");
|
||||
assert.equal(o3.valore, Math.min(vittorieReali, 1), "prima vittoria, cappata a 1");
|
||||
assert.equal(o4.valore, Math.min(vittorieReali, 5), "5 vittorie, cappata a 5");
|
||||
assert.equal(o5.valore, Math.min(vittorieReali, 10), "10 vittorie, cappata a 10");
|
||||
assert.ok(o3.valore <= o4.valore && o4.valore <= o5.valore, "progressione o3 ≤ o4 ≤ o5");
|
||||
},
|
||||
);
|
||||
|
||||
await prova("la seconda chiamata arriva dalla cache del server", async () => {
|
||||
const t0 = Date.now();
|
||||
const secondo = (await json(await fetch(url("/api/public/csi")))) as DatiCsi;
|
||||
|
||||
@@ -325,6 +325,59 @@ assert.equal(
|
||||
);
|
||||
}
|
||||
|
||||
// --- o3/o4/o5: vittorie in campionato (1/5/10), tutte cappate al target -------
|
||||
{
|
||||
const conVittorie = (n: number) => obiettiviSquadra(giocatori, { ...contestoVuoto, vittorie: n });
|
||||
|
||||
// Senza dato CSI (undefined) o a zero vittorie: tutti fermi a 0, nessun NaN.
|
||||
for (const senzaVittorie of [contestoVuoto, { ...contestoVuoto, vittorie: 0 }]) {
|
||||
const obiettivi = obiettiviSquadra(giocatori, senzaVittorie);
|
||||
assert.equal(trova(obiettivi, "o3").valore, 0);
|
||||
assert.equal(trova(obiettivi, "o4").valore, 0);
|
||||
assert.equal(trova(obiettivi, "o5").valore, 0);
|
||||
}
|
||||
|
||||
// I target restano fissi: 1, 5, 10.
|
||||
assert.deepEqual(
|
||||
[trova(vuoti, "o3").target, trova(vuoti, "o4").target, trova(vuoti, "o5").target],
|
||||
[1, 5, 10],
|
||||
);
|
||||
|
||||
// Progressione realistica: con 1 vittoria tutti e tre valgono 1 (o3 già al target,
|
||||
// o4/o5 solo all'inizio).
|
||||
assert.deepEqual(
|
||||
[1, 2, 3].map((n) => trova(conVittorie(1), `o${n + 2}`).valore),
|
||||
[1, 1, 1],
|
||||
"1 vittoria: o3 al target, o4/o5 ancora lontani ma valgono 1",
|
||||
);
|
||||
const conCinque = conVittorie(5);
|
||||
assert.deepEqual(
|
||||
[trova(conCinque, "o3").valore, trova(conCinque, "o4").valore, trova(conCinque, "o5").valore],
|
||||
[1, 5, 5],
|
||||
"5 vittorie: o3 e o4 al target, o5 a metà",
|
||||
);
|
||||
const conDieci = conVittorie(10);
|
||||
assert.deepEqual(
|
||||
[trova(conDieci, "o3").valore, trova(conDieci, "o4").valore, trova(conDieci, "o5").valore],
|
||||
[1, 5, 10],
|
||||
"10 vittorie: tutti e tre al target",
|
||||
);
|
||||
|
||||
// Oltre il target: o3 e o4 restavano già cappati con Math.min, o5 no (bug fixato:
|
||||
// valore = vittorie invece di Math.min(vittorie, 10), incoerente con gli altri due e
|
||||
// mostrato senza cap in squadra.tsx/index.tsx come "15/10 vittorie").
|
||||
const conQuindici = conVittorie(15);
|
||||
assert.deepEqual(
|
||||
[
|
||||
trova(conQuindici, "o3").valore,
|
||||
trova(conQuindici, "o4").valore,
|
||||
trova(conQuindici, "o5").valore,
|
||||
],
|
||||
[1, 5, 10],
|
||||
"oltre il target tutti e tre restano cappati, o5 incluso",
|
||||
);
|
||||
}
|
||||
|
||||
// --- progressoObiettivo ------------------------------------------------------
|
||||
const o = (valore: number, target: number): ObiettivoSquadra => ({
|
||||
id: "x",
|
||||
|
||||
Reference in New Issue
Block a user