From 9211cad7d1d401233cc10afde0427b539ff47505 Mon Sep 17 00:00:00 2001 From: Chris Parsons Date: Tue, 17 Feb 2026 14:24:07 -0800 Subject: [PATCH] fix: correct test expectations for ICM edge cases and duplicate text queries - ICM tests: fix single participant, zero probabilities, and 2-participant tests to account for simulation only filling min(participants, 8) positions - TeamScoreBreakdown tests: use getAllByText for "150.0" which now appears in both the header and the Actual Points summary card Co-Authored-By: Claude Opus 4.6 --- .../__tests__/TeamScoreBreakdown.test.tsx | 4 +-- app/services/__tests__/icm-calculator.test.ts | 28 +++++++++++++------ 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/app/components/standings/__tests__/TeamScoreBreakdown.test.tsx b/app/components/standings/__tests__/TeamScoreBreakdown.test.tsx index 55fde33..7be2f9c 100644 --- a/app/components/standings/__tests__/TeamScoreBreakdown.test.tsx +++ b/app/components/standings/__tests__/TeamScoreBreakdown.test.tsx @@ -152,7 +152,7 @@ describe("TeamScoreBreakdown", () => { ); expect(screen.getByText("Test Team")).toBeInTheDocument(); - expect(screen.getByText("150.0")).toBeInTheDocument(); + expect(screen.getAllByText("150.0").length).toBeGreaterThanOrEqual(1); }); it("should show team rank badge", () => { @@ -432,7 +432,7 @@ describe("TeamScoreBreakdown", () => { // Should still show team name and points expect(screen.getByText("Test Team")).toBeInTheDocument(); - expect(screen.getByText("150.0")).toBeInTheDocument(); + expect(screen.getAllByText("150.0").length).toBeGreaterThanOrEqual(1); // But not show rank badge expect(screen.queryByText(/Rank #/)).not.toBeInTheDocument(); diff --git a/app/services/__tests__/icm-calculator.test.ts b/app/services/__tests__/icm-calculator.test.ts index d1e3499..8993140 100644 --- a/app/services/__tests__/icm-calculator.test.ts +++ b/app/services/__tests__/icm-calculator.test.ts @@ -112,9 +112,10 @@ describe('icm-calculator', () => { expect(results.size).toBe(1); const probs = icmResultToArray(results.get('1')!); - // With 1 team and 8 positions, each column gets 100%, so row sums to 800% + // With 1 participant, only 1st place is filled (removed from pool after) + expect(probs[0]).toBeCloseTo(1.0, 1); // 100% chance of 1st const sum = probs.reduce((acc, p) => acc + p, 0); - expect(sum).toBeCloseTo(8.0, 1); // 8 positions * 100% each + expect(sum).toBeCloseTo(1.0, 1); }); it('handles zero championship probabilities gracefully', () => { @@ -129,12 +130,17 @@ describe('icm-calculator', () => { expect(results.size).toBe(3); // Should give equal probabilities when all have zero odds - // With 3 teams and 8 positions, each position has 33.33% per team + // With 3 teams, only positions 0-2 are filled (each team removed after placement) results.forEach((result) => { const probs = icmResultToArray(result); - probs.forEach(p => { - expect(p).toBeCloseTo(1/3, 2); // Each team gets equal share of each position - }); + // First 3 positions should each have ~1/3 + for (let i = 0; i < 3; i++) { + expect(probs[i]).toBeCloseTo(1/3, 1); + } + // Positions 3-7 are 0 (no participants left to fill them) + for (let i = 3; i < 8; i++) { + expect(probs[i]).toBe(0); + } }); }); @@ -149,8 +155,9 @@ describe('icm-calculator', () => { expect(results.size).toBe(2); - // Verify columns sum to 1.0 - for (let place = 0; place < 8; place++) { + // With 2 participants, only positions 0-1 are filled + // Verify those columns sum to 1.0 + for (let place = 0; place < 2; place++) { let colSum = 0; results.forEach((result) => { const probs = icmResultToArray(result); @@ -158,6 +165,11 @@ describe('icm-calculator', () => { }); expect(colSum).toBeCloseTo(1.0, 2); } + + // Participant 1 (higher prob) should have higher P(1st) + const probs1 = icmResultToArray(results.get('1')!); + const probs2 = icmResultToArray(results.get('2')!); + expect(probs1[0]).toBeGreaterThan(probs2[0]); }); it('returns empty map for empty input', () => {