import { describe, it, expect, vi, beforeEach } from "vitest"; vi.mock("~/database/context", () => ({ database: vi.fn(), })); import { createTournament, getTournamentById, findTournamentsBySport, findTournamentBySportNameYear, upsertTournament, updateTournamentStatus, deleteTournament, } from "../tournament"; import { database } from "~/database/context"; const SPORT_ID = "sport-1"; const TOURNAMENT_ID = "tournament-1"; const SAMPLE_TOURNAMENT = { id: TOURNAMENT_ID, sportId: SPORT_ID, name: "Australian Open", year: 2026, startsAt: new Date("2026-01-15T00:00:00Z"), endsAt: new Date("2026-01-28T00:00:00Z"), surface: "hard", location: "Melbourne", status: "scheduled" as const, externalKey: "ao-2026", createdAt: new Date("2026-01-01T00:00:00Z"), updatedAt: new Date("2026-01-01T00:00:00Z"), }; function makeInsertDb(returnValue: object) { return { insert: vi.fn().mockReturnValue({ values: vi.fn().mockReturnValue({ returning: vi.fn().mockResolvedValue([returnValue]), }), }), }; } function makeSelectDb(rows: object[]) { return { select: vi.fn().mockReturnValue({ from: vi.fn().mockReturnValue({ where: vi.fn().mockReturnValue({ limit: vi.fn().mockResolvedValue(rows), orderBy: vi.fn().mockResolvedValue(rows), }), }), }), }; } function makeUpdateDb(returnValue: object) { return { update: vi.fn().mockReturnValue({ set: vi.fn().mockReturnValue({ where: vi.fn().mockReturnValue({ returning: vi.fn().mockResolvedValue([returnValue]), }), }), }), }; } beforeEach(() => { vi.clearAllMocks(); }); describe("createTournament", () => { it("inserts a tournament and returns it", async () => { vi.mocked(database).mockReturnValue(makeInsertDb(SAMPLE_TOURNAMENT) as never); const result = await createTournament({ sportId: SPORT_ID, name: "Australian Open", year: 2026, }); expect(result).toEqual(SAMPLE_TOURNAMENT); }); }); describe("getTournamentById", () => { it("returns the tournament when found", async () => { vi.mocked(database).mockReturnValue(makeSelectDb([SAMPLE_TOURNAMENT]) as never); const result = await getTournamentById(TOURNAMENT_ID); expect(result).toEqual(SAMPLE_TOURNAMENT); }); it("returns null when not found", async () => { vi.mocked(database).mockReturnValue(makeSelectDb([]) as never); const result = await getTournamentById("nonexistent"); expect(result).toBeNull(); }); }); describe("findTournamentsBySport", () => { it("returns tournaments ordered by year and date", async () => { const tournaments = [SAMPLE_TOURNAMENT]; vi.mocked(database).mockReturnValue(makeSelectDb(tournaments) as never); const result = await findTournamentsBySport(SPORT_ID); expect(result).toEqual(tournaments); }); }); describe("findTournamentBySportNameYear", () => { it("returns the tournament when found", async () => { vi.mocked(database).mockReturnValue(makeSelectDb([SAMPLE_TOURNAMENT]) as never); const result = await findTournamentBySportNameYear(SPORT_ID, "Australian Open", 2026); expect(result).toEqual(SAMPLE_TOURNAMENT); }); it("returns null when not found", async () => { vi.mocked(database).mockReturnValue(makeSelectDb([]) as never); const result = await findTournamentBySportNameYear(SPORT_ID, "Wimbledon", 2026); expect(result).toBeNull(); }); }); describe("upsertTournament", () => { it("returns existing tournament if found", async () => { vi.mocked(database).mockReturnValue(makeSelectDb([SAMPLE_TOURNAMENT]) as never); const result = await upsertTournament({ sportId: SPORT_ID, name: "Australian Open", year: 2026, }); expect(result).toEqual(SAMPLE_TOURNAMENT); }); it("creates new tournament if not found", async () => { let callCount = 0; vi.mocked(database).mockImplementation(() => { callCount++; return (callCount === 1 ? makeSelectDb([]) : makeInsertDb(SAMPLE_TOURNAMENT)) as never; }); const result = await upsertTournament({ sportId: SPORT_ID, name: "Australian Open", year: 2026, }); expect(result).toEqual(SAMPLE_TOURNAMENT); }); }); describe("updateTournamentStatus", () => { it("updates status and returns the tournament", async () => { const updated = { ...SAMPLE_TOURNAMENT, status: "in_progress" as const }; vi.mocked(database).mockReturnValue(makeUpdateDb(updated) as never); const result = await updateTournamentStatus(TOURNAMENT_ID, "in_progress"); expect(result.status).toBe("in_progress"); }); }); describe("deleteTournament", () => { it("deletes the tournament row by id", async () => { const where = vi.fn().mockResolvedValue(undefined); const db = { delete: vi.fn().mockReturnValue({ where }) }; vi.mocked(database).mockReturnValue(db as never); await deleteTournament(TOURNAMENT_ID); expect(db.delete).toHaveBeenCalledTimes(1); expect(where).toHaveBeenCalledTimes(1); }); it("uses a provided db when passed (transaction)", async () => { const where = vi.fn().mockResolvedValue(undefined); const providedDb = { delete: vi.fn().mockReturnValue({ where }) }; await deleteTournament(TOURNAMENT_ID, providedDb as never); expect(providedDb.delete).toHaveBeenCalledTimes(1); expect(vi.mocked(database)).not.toHaveBeenCalled(); }); });