import { describe, expect, it } from "vitest"; import { computePokerStatsDelta, readPokerStats, xpForPlacement, type PokerPlacementResult, type PokerStats, } from "@/lib/minigames/poker/stats"; function result(overrides: Partial = {}): PokerPlacementResult { return { userId: 1, placement: 1, finalChips: 5000, handsWon: 3, ...overrides }; } function current(overrides: Partial = {}): PokerStats { return { gamesPlayed: 0, wins: 0, secondPlaces: 0, thirdPlaces: 0, fourthPlaces: 0, handsWon: 0, bestScore: 0, xpEarned: 0, ...overrides, }; } describe("xpForPlacement", () => { it("scales 1st place at 40x the player count", () => { expect(xpForPlacement(1, 2)).toBe(80); expect(xpForPlacement(1, 3)).toBe(120); expect(xpForPlacement(1, 4)).toBe(160); }); it("scales 2nd place at 20x the player count", () => { expect(xpForPlacement(2, 2)).toBe(40); expect(xpForPlacement(2, 3)).toBe(60); expect(xpForPlacement(2, 4)).toBe(80); }); it("scales 3rd place at 10x the player count", () => { expect(xpForPlacement(3, 2)).toBe(20); expect(xpForPlacement(3, 3)).toBe(30); expect(xpForPlacement(3, 4)).toBe(40); }); it("scales 4th place at 5x the player count", () => { expect(xpForPlacement(4, 2)).toBe(10); expect(xpForPlacement(4, 3)).toBe(15); expect(xpForPlacement(4, 4)).toBe(20); }); }); describe("computePokerStatsDelta", () => { it("increments gamesPlayed by exactly one", () => { const next = computePokerStatsDelta(current({ gamesPlayed: 7 }), result(), 4); expect(next.gamesPlayed).toBe(8); }); it("increments the wins counter for 1st place only", () => { const next = computePokerStatsDelta(current({ wins: 2 }), result({ placement: 1 }), 4); expect(next.wins).toBe(3); expect(next.secondPlaces).toBe(0); expect(next.thirdPlaces).toBe(0); expect(next.fourthPlaces).toBe(0); }); it("increments the secondPlaces counter for 2nd place only", () => { const next = computePokerStatsDelta( current({ secondPlaces: 1 }), result({ placement: 2 }), 4, ); expect(next.secondPlaces).toBe(2); expect(next.wins).toBe(0); expect(next.thirdPlaces).toBe(0); expect(next.fourthPlaces).toBe(0); }); it("increments the thirdPlaces counter for 3rd place only", () => { const next = computePokerStatsDelta( current({ thirdPlaces: 4 }), result({ placement: 3 }), 4, ); expect(next.thirdPlaces).toBe(5); expect(next.wins).toBe(0); expect(next.secondPlaces).toBe(0); expect(next.fourthPlaces).toBe(0); }); it("increments the fourthPlaces counter for 4th place only", () => { const next = computePokerStatsDelta( current({ fourthPlaces: 1 }), result({ placement: 4 }), 4, ); expect(next.fourthPlaces).toBe(2); expect(next.wins).toBe(0); expect(next.secondPlaces).toBe(0); expect(next.thirdPlaces).toBe(0); }); it("accumulates handsWon on top of the existing total", () => { const next = computePokerStatsDelta( current({ handsWon: 10 }), result({ handsWon: 4 }), 4, ); expect(next.handsWon).toBe(14); }); it("keeps bestScore when the final chip total is lower", () => { const next = computePokerStatsDelta( current({ bestScore: 9000 }), result({ finalChips: 5000 }), 4, ); expect(next.bestScore).toBe(9000); }); it("raises bestScore when the final chip total is higher", () => { const next = computePokerStatsDelta( current({ bestScore: 3000 }), result({ finalChips: 7500 }), 4, ); expect(next.bestScore).toBe(7500); }); it("adds the placement XP to the existing xpEarned total", () => { const next = computePokerStatsDelta( current({ xpEarned: 100 }), result({ placement: 2 }), 3, ); expect(next.xpEarned).toBe(160); }); it("does not mutate the current stats object", () => { const before = current({ gamesPlayed: 1, wins: 1, xpEarned: 160 }); computePokerStatsDelta(before, result(), 4); expect(before).toEqual(current({ gamesPlayed: 1, wins: 1, xpEarned: 160 })); }); }); describe("readPokerStats", () => { it("reads poker stats from a profile that also carries sibling game stats", () => { const profile = { progression: { minigames: { flappyBird: { gamesPlayed: 12, xpEarned: 40 }, poker: { gamesPlayed: 3, wins: 1, xpEarned: 200 }, }, }, }; expect(readPokerStats(profile)).toEqual( current({ gamesPlayed: 3, wins: 1, xpEarned: 200 }), ); }); it("returns all zeros when the poker group is missing", () => { expect(readPokerStats({ progression: { minigames: {} } })).toEqual(current()); }); it("returns all zeros for a nullish profile", () => { expect(readPokerStats(undefined)).toEqual(current()); }); });