From 095f351cb13cdef1274905d2a29dbc3a032b0fbc Mon Sep 17 00:00:00 2001 From: Chris Parsons Date: Wed, 25 Mar 2026 20:41:46 -0700 Subject: [PATCH] Fix scoring-event-dashboard tests after select/sql changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Rename mockSelectDistinct → mockSelect to match implementation change from .selectDistinct() to .select() - Add sql to drizzle-orm mock - Update mock row shapes to include eventDate and gameDate fields - Add two tests covering displayDate derivation from eventDate and gameDate Co-Authored-By: Claude Sonnet 4.6 --- .../__tests__/scoring-event-dashboard.test.ts | 61 ++++++++++++------- 1 file changed, 40 insertions(+), 21 deletions(-) diff --git a/app/models/__tests__/scoring-event-dashboard.test.ts b/app/models/__tests__/scoring-event-dashboard.test.ts index a8de849..214c688 100644 --- a/app/models/__tests__/scoring-event-dashboard.test.ts +++ b/app/models/__tests__/scoring-event-dashboard.test.ts @@ -4,10 +4,10 @@ import { describe, it, expect, vi, beforeEach } from "vitest"; // ── DB mock ────────────────────────────────────────────────────────────────── -// selectDistinct returns a fluent chain; findMany is used in step 2. +// select returns a fluent chain; findMany is used in step 2. const mockFindMany = vi.fn(); -function makeSelectChain(rows: { id: string }[]) { +function makeSelectChain(rows: { id: string; eventDate?: string | null; gameDate?: string | null }[]) { const chain = { from: vi.fn().mockReturnThis(), leftJoin: vi.fn().mockReturnThis(), @@ -16,13 +16,13 @@ function makeSelectChain(rows: { id: string }[]) { return chain; } -const mockSelectDistinct = vi.fn(); +const mockSelect = vi.fn(); const mockDb = { query: { scoringEvents: { findMany: mockFindMany }, }, - selectDistinct: mockSelectDistinct, + select: mockSelect, }; vi.mock("~/database/context", () => ({ @@ -57,6 +57,7 @@ vi.mock("drizzle-orm", () => ({ or: (...args: unknown[]) => ({ type: "or", args }), inArray: (col: unknown, arr: unknown) => ({ type: "inArray", col, arr }), isNotNull: (col: unknown) => ({ type: "isNotNull", col }), + sql: (strings: TemplateStringsArray, ...values: unknown[]) => ({ type: "sql", strings, values }), })); import { getEventsForDates } from "../scoring-event"; @@ -95,18 +96,18 @@ function makeEventRow(overrides: Partial<{ describe("getEventsForDates", () => { beforeEach(() => { vi.clearAllMocks(); - mockSelectDistinct.mockReturnValue(makeSelectChain([])); + mockSelect.mockReturnValue(makeSelectChain([])); }); it("returns empty array and skips DB when no dates given", async () => { const result = await getEventsForDates([]); expect(result).toEqual([]); - expect(mockSelectDistinct).not.toHaveBeenCalled(); + expect(mockSelect).not.toHaveBeenCalled(); expect(mockFindMany).not.toHaveBeenCalled(); }); - it("returns empty array when selectDistinct finds no matching event IDs", async () => { - mockSelectDistinct.mockReturnValue(makeSelectChain([])); + it("returns empty array when select finds no matching event IDs", async () => { + mockSelect.mockReturnValue(makeSelectChain([])); const result = await getEventsForDates(["2026-03-20"]); @@ -115,7 +116,7 @@ describe("getEventsForDates", () => { }); it("maps database rows to DashboardScoringEvent shape", async () => { - mockSelectDistinct.mockReturnValue(makeSelectChain([{ id: "e1" }])); + mockSelect.mockReturnValue(makeSelectChain([{ id: "e1", eventDate: "2026-03-20", gameDate: null }])); mockFindMany.mockResolvedValueOnce([ makeEventRow({ id: "e1", @@ -148,8 +149,8 @@ describe("getEventsForDates", () => { }); it("returns events for multiple dates", async () => { - mockSelectDistinct.mockReturnValue( - makeSelectChain([{ id: "e1" }, { id: "e2" }]) + mockSelect.mockReturnValue( + makeSelectChain([{ id: "e1", eventDate: "2026-03-20", gameDate: null }, { id: "e2", eventDate: "2026-03-21", gameDate: null }]) ); mockFindMany.mockResolvedValueOnce([ makeEventRow({ id: "e1", eventDate: "2026-03-20" }), @@ -163,7 +164,7 @@ describe("getEventsForDates", () => { }); it("includes completed events with isComplete: true", async () => { - mockSelectDistinct.mockReturnValue(makeSelectChain([{ id: "e-done" }])); + mockSelect.mockReturnValue(makeSelectChain([{ id: "e-done", eventDate: "2026-03-20", gameDate: null }])); mockFindMany.mockResolvedValueOnce([ makeEventRow({ id: "e-done", @@ -180,7 +181,7 @@ describe("getEventsForDates", () => { it("includes eventStartsAt when present", async () => { const starts = new Date("2026-03-20T19:30:00Z"); - mockSelectDistinct.mockReturnValue(makeSelectChain([{ id: "e1" }])); + mockSelect.mockReturnValue(makeSelectChain([{ id: "e1", eventDate: "2026-03-20", gameDate: null }])); mockFindMany.mockResolvedValueOnce([ makeEventRow({ id: "e1", eventStartsAt: starts }), ]); @@ -190,19 +191,19 @@ describe("getEventsForDates", () => { expect(result[0].eventStartsAt).toEqual(starts); }); - it("uses two DB calls: selectDistinct then findMany", async () => { - mockSelectDistinct.mockReturnValue(makeSelectChain([{ id: "e1" }])); + it("uses two DB calls: select then findMany", async () => { + mockSelect.mockReturnValue(makeSelectChain([{ id: "e1", eventDate: "2026-03-20", gameDate: null }])); mockFindMany.mockResolvedValueOnce([makeEventRow({ id: "e1" })]); await getEventsForDates(["2026-03-20"]); - expect(mockSelectDistinct).toHaveBeenCalledOnce(); + expect(mockSelect).toHaveBeenCalledOnce(); expect(mockFindMany).toHaveBeenCalledOnce(); }); it("passes event IDs from step 1 into findMany in step 2", async () => { - mockSelectDistinct.mockReturnValue( - makeSelectChain([{ id: "abc" }, { id: "def" }]) + mockSelect.mockReturnValue( + makeSelectChain([{ id: "abc", eventDate: "2026-03-20", gameDate: null }, { id: "def", eventDate: "2026-03-20", gameDate: null }]) ); mockFindMany.mockResolvedValueOnce([]); @@ -216,7 +217,7 @@ describe("getEventsForDates", () => { it("uses leftJoin so bracket events without playoffMatchGames still qualify via eventDate", async () => { const chain = makeSelectChain([]); - mockSelectDistinct.mockReturnValue(chain); + mockSelect.mockReturnValue(chain); await getEventsForDates(["2026-03-20"]); @@ -225,7 +226,7 @@ describe("getEventsForDates", () => { it("includes both eventDate and scheduledAt timestamp bounds in the where clause", async () => { const chain = makeSelectChain([]); - mockSelectDistinct.mockReturnValue(chain); + mockSelect.mockReturnValue(chain); await getEventsForDates(["2026-03-20", "2026-03-21"]); @@ -241,7 +242,7 @@ describe("getEventsForDates", () => { it("excludes schedule_event type via the where clause", async () => { const chain = makeSelectChain([]); - mockSelectDistinct.mockReturnValue(chain); + mockSelect.mockReturnValue(chain); await getEventsForDates(["2026-03-20"]); @@ -251,4 +252,22 @@ describe("getEventsForDates", () => { expect(whereArg).toContain("final_standings"); expect(whereArg).not.toContain("schedule_event"); }); + + it("sets displayDate from eventDate when present", async () => { + mockSelect.mockReturnValue(makeSelectChain([{ id: "e1", eventDate: "2026-03-20", gameDate: null }])); + mockFindMany.mockResolvedValueOnce([makeEventRow({ id: "e1", eventDate: "2026-03-20" })]); + + const result = await getEventsForDates(["2026-03-20"]); + + expect(result[0].displayDate).toBe("2026-03-20"); + }); + + it("sets displayDate from gameDate when eventDate is null", async () => { + mockSelect.mockReturnValue(makeSelectChain([{ id: "e1", eventDate: null, gameDate: "2026-03-20" }])); + mockFindMany.mockResolvedValueOnce([makeEventRow({ id: "e1", eventDate: null })]); + + const result = await getEventsForDates(["2026-03-20"]); + + expect(result[0].displayDate).toBe("2026-03-20"); + }); });