Show visual dividers in the available participants list indicating where your future draft picks fall relative to the current pick position. Dividers are suppressed when any filter is active (search, sport filter, hide drafted, etc.) since positional references are meaningless in a filtered view. - Add getProjectedPicks() to draft-order.ts for computing future pick positions in a snake draft - Interleave divider items into the virtualized list in AvailableParticipantsSection - Extract ListItem type to module scope - Add tests for getProjectedPicks, divider rendering, and filter suppression
210 lines
6 KiB
TypeScript
210 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 },
|
|
]);
|
|
});
|
|
});
|