import { describe, it, expect } from "vitest"; import { computeCoronaStates } from "../corona-states"; const RULES = { pointsFor1st: 100, pointsFor2nd: 70, pointsFor3rd: 50, pointsFor4th: 40, pointsFor5th: 25, pointsFor6th: 25, pointsFor7th: 15, pointsFor8th: 15, }; function pick(id: string, scoringPattern: string | null, sportsSeasonId = "ss-1") { return { participant: { id, sportsSeasonId }, scoringPattern }; } function results( rows: Array<{ participantId: string; finalPosition: number | null; isPartialScore?: boolean }> ) { return new Map( rows.map((r) => [r.participantId, { isPartialScore: false, ...r }]) ); } describe("computeCoronaStates", () => { const noTies = new Map>(); it("splits points for a tied qualifying_points pick", () => { // Rahm tied for 8th. 9th is outside the scoring range and contributes 0, // so (15 + 0) / 2 = 7.5 → 8. Before the shared helper this path awarded the // full 15 while the standings awarded the split — the reported bug. const states = computeCoronaStates( [pick("rahm", "qualifying_points")], results([{ participantId: "rahm", finalPosition: 8 }]), new Map(), RULES, RULES.pointsFor1st, new Map([["ss-1", new Map([[8, 2]])]]) ); expect(states.rahm).toEqual({ type: "scored", points: 8, brightness: 8 / 100, }); }); it("awards the full value when the placement is untied", () => { const states = computeCoronaStates( [pick("rahm", "qualifying_points")], results([{ participantId: "rahm", finalPosition: 8 }]), new Map(), RULES, RULES.pointsFor1st, noTies ); expect(states.rahm).toMatchObject({ type: "scored", points: 15 }); }); it("still averages bracket tiers via the bracket template", () => { const states = computeCoronaStates( [pick("team-a", "playoff_bracket")], results([{ participantId: "team-a", finalPosition: 5 }]), new Map([["ss-1", null]]), RULES, RULES.pointsFor1st, noTies ); // Four QF losers share 5th-8th: (25 + 25 + 15 + 15) / 4 = 20 expect(states["team-a"]).toMatchObject({ type: "scored", points: 20 }); }); it("scores other patterns straight off the placement", () => { const states = computeCoronaStates( [pick("driver", "season_standings")], results([{ participantId: "driver", finalPosition: 2 }]), new Map(), RULES, RULES.pointsFor1st, noTies ); expect(states.driver).toMatchObject({ type: "scored", points: 70 }); }); it("marks picks with no result as pending", () => { const states = computeCoronaStates( [pick("rahm", "qualifying_points")], results([]), new Map(), RULES, RULES.pointsFor1st, noTies ); expect(states.rahm).toEqual({ type: "pending" }); }); it("marks a finalized zero placement as eliminated", () => { const states = computeCoronaStates( [pick("rahm", "qualifying_points")], results([{ participantId: "rahm", finalPosition: 0 }]), new Map(), RULES, RULES.pointsFor1st, noTies ); expect(states.rahm).toEqual({ type: "eliminated", points: 0 }); }); it("keeps brightness within range when a tier exceeds maxPoints", () => { const states = computeCoronaStates( [pick("champ", "season_standings")], results([{ participantId: "champ", finalPosition: 1 }]), new Map(), RULES, 10, // deliberately below the 1st-place award noTies ); expect(states.champ).toMatchObject({ brightness: 1 }); }); });