211 lines
6 KiB
TypeScript
211 lines
6 KiB
TypeScript
|
|
import { describe, it, expect } from "vitest";
|
||
|
|
import { getTeamForPick, getProjectedPicks } from "~/lib/draft-order";
|
||
|
|
|
||
|
|
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 },
|
||
|
|
]);
|
||
|
|
});
|
||
|
|
});
|