brackt/app/components/__tests__/ParticipantSelectionDialog.test.tsx
Chris Parsons 049ec8a596
Show why a participant is ineligible to draft (#378)
Closes #72

Upgrades ineligibleReasons from Record<string, string> to a structured
{code, message} type so the UI can render the human-readable reason
inline below the Ineligible badge in both AvailableParticipantsSection
and ParticipantSelectionDialog. API routes surface the message in 400
responses unchanged.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 21:54:14 -07:00

59 lines
1.7 KiB
TypeScript

import { describe, it, expect, vi } from "vitest";
import { render, screen } from "@testing-library/react";
import { ParticipantSelectionDialog } from "~/components/draft/ParticipantSelectionDialog";
const defaultProps = {
open: true,
onOpenChange: vi.fn(),
title: "Force pick",
description: "Choose a participant",
participants: [
{ id: "1", name: "Player A", sport: { id: "s1", name: "NFL" } },
{ id: "2", name: "Player B", sport: { id: "s2", name: "NBA" } },
],
draftedParticipantIds: new Set<string>(),
eligibility: null,
uniqueSports: ["NFL", "NBA"],
onSelect: vi.fn(),
};
describe("ParticipantSelectionDialog", () => {
it("renders inline out-of-flex-spots reason and disables drafting", () => {
render(
<ParticipantSelectionDialog
{...defaultProps}
eligibility={{
eligibleSportIds: new Set(["s2"]),
ineligibleReasons: {
s1: {
code: "no_flex_spots",
message: "Out of flex spots (2/2)",
},
},
}}
/>
);
expect(screen.getByText("Out of flex spots (2/2)")).toBeInTheDocument();
expect(screen.getAllByRole("button", { name: "Draft" })[0]).toBeDisabled();
});
it("renders inline no-extras reason for blocked flex picks", () => {
render(
<ParticipantSelectionDialog
{...defaultProps}
eligibility={{
eligibleSportIds: new Set(["s2"]),
ineligibleReasons: {
s1: {
code: "no_extra_participants",
message: "Not enough NFL participants for remaining teams",
},
},
}}
/>
);
expect(screen.getByText("Not enough NFL participants for remaining teams")).toBeInTheDocument();
});
});