import { describe, it, expect, vi, beforeEach } from "vitest"; vi.mock("~/database/context", () => ({ database: vi.fn(), })); import { upsertSeasonMatch, upsertSeasonMatchBulk, upsertMatchSubGame, } from "../season-match"; import { database } from "~/database/context"; const SPORTS_SEASON_ID = "ss-1"; const SCORING_EVENT_ID = "evt-1"; const P1_ID = "p1"; const P2_ID = "p2"; const WINNER_ID = "p1"; const EXTERNAL_ID = "panda_123"; function makeUpsertDb(returnValue: object) { const returningFn = vi.fn().mockResolvedValue([returnValue]); const onConflictFn = vi.fn().mockReturnValue({ returning: returningFn }); const valuesFn = vi.fn().mockReturnValue({ onConflictDoUpdate: onConflictFn }); return { insert: vi.fn().mockReturnValue({ values: valuesFn }), _returning: returningFn, _onConflict: onConflictFn, _values: valuesFn, }; } function makeBulkUpsertDb(returnValues: object[]) { const returningFn = vi.fn().mockResolvedValue(returnValues); const onConflictFn = vi.fn().mockReturnValue({ returning: returningFn }); const valuesFn = vi.fn().mockReturnValue({ onConflictDoUpdate: onConflictFn }); return { insert: vi.fn().mockReturnValue({ values: valuesFn }), _returning: returningFn, }; } const SAMPLE_MATCH = { id: "match-1", sportsSeasonId: SPORTS_SEASON_ID, scoringEventId: SCORING_EVENT_ID, participant1Id: P1_ID, participant2Id: P2_ID, winnerId: WINNER_ID, participant1Score: 2, participant2Score: 1, matchStage: 1, matchRound: 3, matchday: null, isSeries: true, status: "complete" as const, scheduledAt: null, startedAt: null, completedAt: new Date("2025-01-15T14:00:00Z"), externalMatchId: EXTERNAL_ID, createdAt: new Date(), updatedAt: new Date(), }; describe("upsertSeasonMatch", () => { beforeEach(() => { vi.clearAllMocks(); }); it("inserts a match and returns it", async () => { const mockDb = makeUpsertDb(SAMPLE_MATCH); vi.mocked(database).mockReturnValue(mockDb as unknown as ReturnType); const result = await upsertSeasonMatch({ sportsSeasonId: SPORTS_SEASON_ID, scoringEventId: SCORING_EVENT_ID, participant1Id: P1_ID, participant2Id: P2_ID, winnerId: WINNER_ID, participant1Score: 2, participant2Score: 1, matchStage: 1, matchRound: 3, isSeries: true, status: "complete", completedAt: new Date("2025-01-15T14:00:00Z"), externalMatchId: EXTERNAL_ID, }); expect(result.id).toBe("match-1"); expect(result.matchStage).toBe(1); expect(result.matchRound).toBe(3); expect(result.status).toBe("complete"); expect(mockDb.insert).toHaveBeenCalledOnce(); expect(mockDb._values).toHaveBeenCalledOnce(); expect(mockDb._onConflict).toHaveBeenCalledOnce(); }); it("defaults isSeries to false when not provided", async () => { const expectedMatch = { ...SAMPLE_MATCH, isSeries: false }; const mockDb = makeUpsertDb(expectedMatch); vi.mocked(database).mockReturnValue(mockDb as unknown as ReturnType); const result = await upsertSeasonMatch({ sportsSeasonId: SPORTS_SEASON_ID, externalMatchId: "ext_1", status: "scheduled", }); const valuesCall = mockDb._values.mock.calls[0][0]; expect(valuesCall.isSeries).toBe(false); expect(result.isSeries).toBe(false); }); it("allows null matchStage and matchRound for non-CS2 sports", async () => { const mlbMatch = { ...SAMPLE_MATCH, matchStage: null, matchRound: null, matchday: null, isSeries: false }; const mockDb = makeUpsertDb(mlbMatch); vi.mocked(database).mockReturnValue(mockDb as unknown as ReturnType); const result = await upsertSeasonMatch({ sportsSeasonId: SPORTS_SEASON_ID, externalMatchId: "mlb_game_456", status: "complete", participant1Score: 5, participant2Score: 3, }); const valuesCall = mockDb._values.mock.calls[0][0]; expect(valuesCall.matchStage).toBeUndefined(); expect(valuesCall.matchRound).toBeUndefined(); expect(result.matchStage).toBeNull(); expect(result.matchRound).toBeNull(); }); }); describe("upsertSeasonMatchBulk", () => { beforeEach(() => { vi.clearAllMocks(); }); it("returns empty array for empty input", async () => { vi.mocked(database).mockReturnValue({} as ReturnType); const result = await upsertSeasonMatchBulk([]); expect(result).toEqual([]); }); it("bulk upserts multiple matches", async () => { const match2 = { ...SAMPLE_MATCH, id: "match-2", matchRound: 4, externalMatchId: "panda_456" }; const mockDb = makeBulkUpsertDb([SAMPLE_MATCH, match2]); vi.mocked(database).mockReturnValue(mockDb as unknown as ReturnType); const result = await upsertSeasonMatchBulk([ { sportsSeasonId: SPORTS_SEASON_ID, externalMatchId: EXTERNAL_ID, status: "complete", matchStage: 1, matchRound: 3 }, { sportsSeasonId: SPORTS_SEASON_ID, externalMatchId: "panda_456", status: "complete", matchStage: 1, matchRound: 4 }, ]); expect(result).toHaveLength(2); expect(mockDb.insert).toHaveBeenCalledOnce(); }); }); describe("upsertMatchSubGame", () => { beforeEach(() => { vi.clearAllMocks(); }); it("upserts a map sub-game", async () => { const subGame = { id: "sg-1", seasonMatchId: "match-1", gameNumber: 1, gameLabel: "Mirage", participant1Score: 16, participant2Score: 14, winnerId: P1_ID, status: "complete" as const, startedAt: null, completedAt: new Date(), externalGameId: "map_1", createdAt: new Date(), updatedAt: new Date(), }; const mockDb = makeUpsertDb(subGame); vi.mocked(database).mockReturnValue(mockDb as unknown as ReturnType); const result = await upsertMatchSubGame({ seasonMatchId: "match-1", gameNumber: 1, gameLabel: "Mirage", participant1Score: 16, participant2Score: 14, winnerId: P1_ID, status: "complete", externalGameId: "map_1", }); expect(result.gameLabel).toBe("Mirage"); expect(result.participant1Score).toBe(16); expect(result.gameNumber).toBe(1); expect(mockDb.insert).toHaveBeenCalledOnce(); expect(mockDb._onConflict).toHaveBeenCalledOnce(); }); it("allows null gameLabel for non-named sub-games", async () => { const subGame = { id: "sg-2", seasonMatchId: "match-1", gameNumber: 2, gameLabel: null, participant1Score: 3, participant2Score: 1, winnerId: P1_ID, status: "complete" as const, startedAt: null, completedAt: new Date(), externalGameId: null, createdAt: new Date(), updatedAt: new Date(), }; const mockDb = makeUpsertDb(subGame); vi.mocked(database).mockReturnValue(mockDb as unknown as ReturnType); const result = await upsertMatchSubGame({ seasonMatchId: "match-1", gameNumber: 2, participant1Score: 3, participant2Score: 1, status: "complete", }); expect(result.gameLabel).toBeNull(); expect(result.gameNumber).toBe(2); }); });