import { describe, it, expect, vi, beforeEach } from "vitest"; vi.mock("~/database/context", () => ({ database: vi.fn(), })); // Mock the schema so the schema module doesn't execute drizzle builder calls, // following the same pattern as scoring-event-dashboard.test.ts. vi.mock("~/database/schema", () => ({ sportsSeasons: { id: "ss.id", sportId: "ss.sport_id", name: "ss.name", year: "ss.year", draftOn: "ss.draft_on", draftOff: "ss.draft_off", }, })); vi.mock("drizzle-orm", () => ({ eq: (col: unknown, val: unknown) => ({ type: "eq", col, val }), sql: (strings: TemplateStringsArray, ...values: unknown[]) => ({ type: "sql", strings, values }), lte: (col: unknown, val: unknown) => ({ type: "lte", col, val }), gte: (col: unknown, val: unknown) => ({ type: "gte", col, val }), and: (...args: unknown[]) => ({ type: "and", args }), desc: (col: unknown) => ({ type: "desc", col }), asc: (col: unknown) => ({ type: "asc", col }), })); import { findAllSportsSeasons, findDraftableSportsSeasons, findDraftScheduleForHorizon, } from "../sports-season"; import { database } from "~/database/context"; const today = new Date().toISOString().slice(0, 10); const future = "2099-12-31"; const pastStart = "2020-01-01"; const pastEnd = "2020-12-31"; const mockSeasons = [ { id: "season-1", name: "2025 NBA Playoffs", draftOn: today, draftOff: future, year: 2025, status: "upcoming", sport: { name: "NBA" }, participants: [] }, { id: "season-2", name: "2025 F1 Season", draftOn: today, draftOff: future, year: 2025, status: "upcoming", sport: { name: "F1" }, participants: [] }, { id: "season-3", name: "2024 Old Golf", draftOn: pastStart, draftOff: pastEnd, year: 2024, status: "completed", sport: { name: "Golf" }, participants: [] }, ]; function makeMockDb(seasons: Record[]) { return { query: { sportsSeasons: { findMany: vi.fn().mockResolvedValue(seasons), }, }, }; } beforeEach(() => { vi.clearAllMocks(); }); describe("findAllSportsSeasons", () => { it("returns all sport seasons regardless of draft window", async () => { vi.mocked(database).mockReturnValue(makeMockDb(mockSeasons) as never); const result = await findAllSportsSeasons(); expect(result).toHaveLength(3); }); it("sorts active before upcoming before completed", async () => { const seasons = [ { id: "s1", name: "Completed", draftOn: pastStart, draftOff: pastEnd, year: 2024, status: "completed", sport: { name: "Sport" } }, { id: "s2", name: "Active", draftOn: today, draftOff: future, year: 2025, status: "active", sport: { name: "Sport" } }, { id: "s3", name: "Upcoming", draftOn: today, draftOff: future, year: 2026, status: "upcoming", sport: { name: "Sport" } }, ]; vi.mocked(database).mockReturnValue(makeMockDb(seasons) as never); const result = await findAllSportsSeasons(); expect(result.map((s) => s.status)).toEqual(["active", "upcoming", "completed"]); }); it("sorts by sport name alphabetically within the same status", async () => { const seasons = [ { id: "s1", name: "Zebra Season", draftOn: today, draftOff: future, year: 2025, status: "active", sport: { name: "Zebra" } }, { id: "s2", name: "Apple Season", draftOn: today, draftOff: future, year: 2025, status: "active", sport: { name: "Apple" } }, { id: "s3", name: "Mango Season", draftOn: today, draftOff: future, year: 2025, status: "active", sport: { name: "Mango" } }, ]; vi.mocked(database).mockReturnValue(makeMockDb(seasons) as never); const result = await findAllSportsSeasons(); expect(result.map((s) => s.sport.name)).toEqual(["Apple", "Mango", "Zebra"]); }); it("sorts by year ascending within the same status and sport name", async () => { const seasons = [ { id: "s1", name: "NFL 2026", draftOn: today, draftOff: future, year: 2026, status: "upcoming", sport: { name: "NFL" } }, { id: "s2", name: "NFL 2024", draftOn: today, draftOff: future, year: 2024, status: "upcoming", sport: { name: "NFL" } }, { id: "s3", name: "NFL 2025", draftOn: today, draftOff: future, year: 2025, status: "upcoming", sport: { name: "NFL" } }, ]; vi.mocked(database).mockReturnValue(makeMockDb(seasons) as never); const result = await findAllSportsSeasons(); expect(result.map((s) => s.year)).toEqual([2024, 2025, 2026]); }); }); describe("findDraftableSportsSeasons", () => { it("returns only currently-draftable seasons", async () => { const draftableOnly = mockSeasons.filter((s) => s.draftOn <= today && today <= s.draftOff); const mockDb = makeMockDb(draftableOnly); vi.mocked(database).mockReturnValue(mockDb as never); const result = await findDraftableSportsSeasons(); expect(result).toHaveLength(2); expect(result.every((s) => s.draftOn <= today && today <= s.draftOff)).toBe(true); }); it("returns empty array when no seasons fall within a draft window", async () => { vi.mocked(database).mockReturnValue(makeMockDb([]) as never); const result = await findDraftableSportsSeasons(); expect(result).toHaveLength(0); }); it("calls findMany with a where clause", async () => { const mockDb = makeMockDb([]); vi.mocked(database).mockReturnValue(mockDb as never); await findDraftableSportsSeasons(); expect(mockDb.query.sportsSeasons.findMany).toHaveBeenCalledWith( expect.objectContaining({ where: expect.anything(), }) ); }); }); describe("findDraftScheduleForHorizon", () => { const horizonWindows = [ { id: "w1", name: "2026 NBA Playoffs", year: 2026, status: "upcoming", draftOn: today, draftOff: future, sport: { id: "nba", name: "NBA", slug: "nba", iconUrl: null }, }, { id: "w2", name: "2026 F1 Season", year: 2026, status: "active", draftOn: today, draftOff: future, sport: { id: "f1", name: "F1", slug: "f1", iconUrl: null }, }, ]; it("maps rows to windows carrying their sport info", async () => { vi.mocked(database).mockReturnValue(makeMockDb(horizonWindows) as never); const result = await findDraftScheduleForHorizon(6); expect(result).toHaveLength(2); expect(result[0]).toMatchObject({ id: "w1", draftOn: today, draftOff: future, sport: { id: "nba", name: "NBA" }, }); }); it("returns an empty array when no windows overlap the horizon", async () => { vi.mocked(database).mockReturnValue(makeMockDb([]) as never); const result = await findDraftScheduleForHorizon(12); expect(result).toHaveLength(0); }); it("queries with a where clause, ordering, and the sport relation", async () => { const mockDb = makeMockDb([]); vi.mocked(database).mockReturnValue(mockDb as never); await findDraftScheduleForHorizon(6); expect(mockDb.query.sportsSeasons.findMany).toHaveBeenCalledWith( expect.objectContaining({ where: expect.anything(), orderBy: expect.anything(), with: expect.anything(), }) ); }); });