import { afterEach, beforeEach, describe, expect, test } from "vitest"; import { db } from "~/db/sql"; import { dbInsertUsers, dbReset } from "~/utils/Test"; import type { TournamentSummary } from "../tournament-bracket/core/summarizer.server"; import * as TournamentRepository from "./TournamentRepository.server"; const createTournament = () => db .insertInto("Tournament") .values({ mapPickingStyle: "TO", settings: JSON.stringify({ bracketProgression: [] }), }) .returning("id") .executeTakeFirstOrThrow(); const createTeam = (tournamentId: number) => db .insertInto("TournamentTeam") .values({ tournamentId, name: "team", inviteCode: `inv-${tournamentId}`, }) .returning("id") .executeTakeFirstOrThrow(); const insertPriorSkill = (args: { userId: number; season: number; matchesCount: number; }) => db .insertInto("Skill") .values({ userId: args.userId, season: args.season, matchesCount: args.matchesCount, mu: 25, sigma: 8.333, ordinal: 0, }) .execute(); const emptySummary = ( skills: TournamentSummary["skills"], ): TournamentSummary => ({ skills, seedingSkills: [], mapResultDeltas: [], playerResultDeltas: [], tournamentResults: [], spDiffs: null, setResults: new Map(), }); const insertPriorTeamSkill = (args: { identifier: string; season: number; matchesCount: number; }) => db .insertInto("Skill") .values({ identifier: args.identifier, season: args.season, matchesCount: args.matchesCount, mu: 25, sigma: 8.333, ordinal: 0, }) .execute(); describe("TournamentRepository.finalize", () => { beforeEach(async () => { await dbInsertUsers(2); }); afterEach(() => { dbReset(); }); test("matchesCount on a new season's Skill row does not include prior seasons", async () => { await insertPriorSkill({ userId: 1, season: 0, matchesCount: 100 }); const { id: tournamentId } = await createTournament(); await TournamentRepository.finalize({ tournamentId, season: 1, summary: emptySummary([ { userId: 1, identifier: null, mu: 25, sigma: 8.333, matchesCount: 5, }, ]), }); const inserted = await db .selectFrom("Skill") .select("matchesCount") .where("userId", "=", 1) .where("season", "=", 1) .executeTakeFirstOrThrow(); expect(inserted.matchesCount).toBe(5); }); test("team matchesCount on a new season's Skill row does not include prior seasons", async () => { await insertPriorTeamSkill({ identifier: "1-2", season: 0, matchesCount: 100, }); const { id: tournamentId } = await createTournament(); await TournamentRepository.finalize({ tournamentId, season: 1, summary: emptySummary([ { userId: null, identifier: "1-2", mu: 25, sigma: 8.333, matchesCount: 5, }, ]), }); const inserted = await db .selectFrom("Skill") .select("matchesCount") .where("identifier", "=", "1-2") .where("season", "=", 1) .executeTakeFirstOrThrow(); expect(inserted.matchesCount).toBe(5); }); test("finalizes and records placements when season is undefined (between-seasons tournament)", async () => { await insertPriorSkill({ userId: 1, season: 0, matchesCount: 100 }); const { id: tournamentId } = await createTournament(); const { id: tournamentTeamId } = await createTeam(tournamentId); await TournamentRepository.finalize({ tournamentId, season: undefined, summary: { skills: [], seedingSkills: [], mapResultDeltas: [], playerResultDeltas: [], tournamentResults: [ { userId: 1, placement: 1, participantCount: 1, tournamentTeamId, div: null, }, ], spDiffs: null, setResults: new Map([[1, ["W"]]]), }, }); const tournament = await db .selectFrom("Tournament") .select("isFinalized") .where("id", "=", tournamentId) .executeTakeFirstOrThrow(); const newSkills = await db .selectFrom("Skill") .select("id") .where("tournamentId", "=", tournamentId) .execute(); const placement = await db .selectFrom("TournamentResult") .select("placement") .where("tournamentId", "=", tournamentId) .where("userId", "=", 1) .executeTakeFirstOrThrow(); expect(tournament.isFinalized).toBe(1); expect(newSkills).toHaveLength(0); expect(placement.placement).toBe(1); }); test("matchesCount accumulates across tournaments within the same season", async () => { const { id: firstTournamentId } = await createTournament(); await TournamentRepository.finalize({ tournamentId: firstTournamentId, season: 1, summary: emptySummary([ { userId: 1, identifier: null, mu: 25, sigma: 8.333, matchesCount: 5, }, ]), }); const { id: secondTournamentId } = await createTournament(); await TournamentRepository.finalize({ tournamentId: secondTournamentId, season: 1, summary: emptySummary([ { userId: 1, identifier: null, mu: 25, sigma: 8.333, matchesCount: 3, }, ]), }); const second = await db .selectFrom("Skill") .select("matchesCount") .where("userId", "=", 1) .where("tournamentId", "=", secondTournamentId) .executeTakeFirstOrThrow(); expect(second.matchesCount).toBe(8); }); });