diff --git a/src/lib/obiettivi.ts b/src/lib/obiettivi.ts index fe36c54..2ba8d47 100644 --- a/src/lib/obiettivi.ts +++ b/src/lib/obiettivi.ts @@ -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: "🏆", diff --git a/test/integration/api.test.ts b/test/integration/api.test.ts index e37d8ad..6ec39fb 100644 --- a/test/integration/api.test.ts +++ b/test/integration/api.test.ts @@ -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; diff --git a/test/unit/obiettivi.test.ts b/test/unit/obiettivi.test.ts index bb00dda..81115c8 100644 --- a/test/unit/obiettivi.test.ts +++ b/test/unit/obiettivi.test.ts @@ -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",