brackt/app/lib/__tests__/draft-order.test.ts
Claude 4cb7424ae4
Address code review feedback on draft order bug fix
- Move buildDraftOrderTeams to app/lib/draft-order.ts so it is importable
  and testable; remove the local copy from the settings component
- Add unit tests for buildDraftOrderTeams covering the empty, full, and
  partial-slot cases
- Tighten the draft slot guard from existingSlots.length > 0 to
  existingSlots.length === currentTeamCount so partial legacy states are
  treated the same as "order not set"
- Condense the 3-line server comment to a single line per project style
- Rename getNumTeamsInSeason → getNumDraftSlotsBySeasonId to reflect what
  the function actually counts, and update its one call site
- Add tests for the server-side slot-creation guard logic

https://claude.ai/code/session_01M3H55gnMxRztJK9KMXqqZo
2026-05-20 01:07:34 +00:00

234 lines
6.8 KiB
TypeScript

import { describe, it, expect } from "vitest";
import { buildDraftOrderTeams, getTeamForPick, getProjectedPicks } from "~/lib/draft-order";
describe("buildDraftOrderTeams", () => {
const teams = [
{ id: "t1" }, { id: "t2" }, { id: "t3" },
];
it("returns all teams in natural order when no slots exist", () => {
expect(buildDraftOrderTeams([], teams)).toEqual(["t1", "t2", "t3"]);
});
it("returns slot order when all teams are slotted", () => {
const slots = [{ teamId: "t3" }, { teamId: "t1" }, { teamId: "t2" }];
expect(buildDraftOrderTeams(slots, teams)).toEqual(["t3", "t1", "t2"]);
});
it("appends unslotted teams after slotted ones in partial state", () => {
const slots = [{ teamId: "t2" }];
expect(buildDraftOrderTeams(slots, teams)).toEqual(["t2", "t1", "t3"]);
});
it("returns empty array when both slots and teams are empty", () => {
expect(buildDraftOrderTeams([], [])).toEqual([]);
});
});
function makeSlots(teamCount: number) {
return Array.from({ length: teamCount }, (_, i) => ({
draftOrder: i + 1,
teamId: `team-${i + 1}`,
}));
}
describe("getTeamForPick", () => {
const slots = makeSlots(4);
it("returns correct team for round 1 (forward)", () => {
expect(getTeamForPick(1, slots)?.teamId).toBe("team-1");
expect(getTeamForPick(2, slots)?.teamId).toBe("team-2");
expect(getTeamForPick(3, slots)?.teamId).toBe("team-3");
expect(getTeamForPick(4, slots)?.teamId).toBe("team-4");
});
it("returns correct team for round 2 (snake reversed)", () => {
expect(getTeamForPick(5, slots)?.teamId).toBe("team-4");
expect(getTeamForPick(6, slots)?.teamId).toBe("team-3");
expect(getTeamForPick(7, slots)?.teamId).toBe("team-2");
expect(getTeamForPick(8, slots)?.teamId).toBe("team-1");
});
it("returns correct team for round 3 (forward again)", () => {
expect(getTeamForPick(9, slots)?.teamId).toBe("team-1");
expect(getTeamForPick(10, slots)?.teamId).toBe("team-2");
expect(getTeamForPick(11, slots)?.teamId).toBe("team-3");
expect(getTeamForPick(12, slots)?.teamId).toBe("team-4");
});
it("returns undefined for empty slots", () => {
expect(getTeamForPick(1, [])).toBeUndefined();
});
});
describe("getProjectedPicks", () => {
it("returns empty array when no draft slots", () => {
const result = getProjectedPicks({
draftSlots: [],
userTeamId: "team-1",
currentPick: 1,
totalRounds: 10,
existingPicks: [],
});
expect(result).toEqual([]);
});
it("returns empty array when user has no team in slots", () => {
const result = getProjectedPicks({
draftSlots: makeSlots(4),
userTeamId: "team-999",
currentPick: 1,
totalRounds: 10,
existingPicks: [],
});
expect(result).toEqual([]);
});
describe("4-team snake draft, user at position 1", () => {
const slots = makeSlots(4);
it("computes picks from start of draft", () => {
const result = getProjectedPicks({
draftSlots: slots,
userTeamId: "team-1",
currentPick: 1,
totalRounds: 4,
existingPicks: [],
});
expect(result).toEqual([
{ round: 1, pickNumber: 1, picksFromNow: 0 },
{ round: 2, pickNumber: 8, picksFromNow: 7 },
{ round: 3, pickNumber: 9, picksFromNow: 8 },
{ round: 4, pickNumber: 16, picksFromNow: 15 },
]);
});
it("computes picks from mid-draft, skipping past picks", () => {
const result = getProjectedPicks({
draftSlots: slots,
userTeamId: "team-1",
currentPick: 5,
totalRounds: 4,
existingPicks: [
{ pickNumber: 1, teamId: "team-1" },
],
});
expect(result).toEqual([
{ round: 2, pickNumber: 8, picksFromNow: 3 },
{ round: 3, pickNumber: 9, picksFromNow: 4 },
{ round: 4, pickNumber: 16, picksFromNow: 11 },
]);
});
it("skips rounds already picked even if current pick is before them", () => {
const result = getProjectedPicks({
draftSlots: slots,
userTeamId: "team-1",
currentPick: 1,
totalRounds: 4,
existingPicks: [
{ pickNumber: 1, teamId: "team-1" },
{ pickNumber: 8, teamId: "team-1" },
],
});
expect(result).toEqual([
{ round: 3, pickNumber: 9, picksFromNow: 8 },
{ round: 4, pickNumber: 16, picksFromNow: 15 },
]);
});
});
describe("4-team snake draft, user at position 3", () => {
const slots = makeSlots(4);
it("computes correct snake positions", () => {
const result = getProjectedPicks({
draftSlots: slots,
userTeamId: "team-3",
currentPick: 1,
totalRounds: 4,
existingPicks: [],
});
expect(result).toEqual([
{ round: 1, pickNumber: 3, picksFromNow: 2 },
{ round: 2, pickNumber: 6, picksFromNow: 5 },
{ round: 3, pickNumber: 11, picksFromNow: 10 },
{ round: 4, pickNumber: 14, picksFromNow: 13 },
]);
});
});
describe("4-team snake draft, user at position 4 (last)", () => {
const slots = makeSlots(4);
it("picks first in round 2 due to snake reversal", () => {
const result = getProjectedPicks({
draftSlots: slots,
userTeamId: "team-4",
currentPick: 1,
totalRounds: 4,
existingPicks: [],
});
expect(result).toEqual([
{ round: 1, pickNumber: 4, picksFromNow: 3 },
{ round: 2, pickNumber: 5, picksFromNow: 4 },
{ round: 3, pickNumber: 12, picksFromNow: 11 },
{ round: 4, pickNumber: 13, picksFromNow: 12 },
]);
});
});
it("returns empty when all picks are in the past", () => {
const result = getProjectedPicks({
draftSlots: makeSlots(4),
userTeamId: "team-1",
currentPick: 17,
totalRounds: 4,
existingPicks: [
{ pickNumber: 1, teamId: "team-1" },
{ pickNumber: 8, teamId: "team-1" },
{ pickNumber: 9, teamId: "team-1" },
{ pickNumber: 16, teamId: "team-1" },
],
});
expect(result).toEqual([]);
});
it("handles 8-team snake draft correctly", () => {
const slots = makeSlots(8);
const result = getProjectedPicks({
draftSlots: slots,
userTeamId: "team-5",
currentPick: 1,
totalRounds: 3,
existingPicks: [],
});
expect(result).toEqual([
{ round: 1, pickNumber: 5, picksFromNow: 4 },
{ round: 2, pickNumber: 12, picksFromNow: 11 },
{ round: 3, pickNumber: 21, picksFromNow: 20 },
]);
});
it("excludes picks before currentPick", () => {
const result = getProjectedPicks({
draftSlots: makeSlots(4),
userTeamId: "team-1",
currentPick: 9,
totalRounds: 4,
existingPicks: [],
});
expect(result).toEqual([
{ round: 3, pickNumber: 9, picksFromNow: 0 },
{ round: 4, pickNumber: 16, picksFromNow: 7 },
]);
});
});