mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-05 02:41:56 +00:00
chore(ui): repair failing vitest tests after shadcn migration (batch B)
Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
This commit is contained in:
parent
6df2178740
commit
a55a2bae7e
2 changed files with 121 additions and 68 deletions
|
|
@ -1,4 +1,4 @@
|
|||
import { screen, waitFor } from "@testing-library/react";
|
||||
import { screen, waitFor, within } from "@testing-library/react";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { renderWithProviders } from "../../../../tests/test-utils";
|
||||
|
|
@ -40,6 +40,19 @@ const mockEmptyPages = {
|
|||
pages: [{ aliases: [], total_count: 0, current_page: 1, total_pages: 1, size: 50 }],
|
||||
};
|
||||
|
||||
// The popover renders option rows as plain <button> elements inside the
|
||||
// popover content. This helper fetches them scoped to the open popover.
|
||||
const getAliasButton = (name: string) => {
|
||||
const dialog = screen.queryByRole("dialog");
|
||||
const scope = dialog ? within(dialog) : screen;
|
||||
return scope.getByRole("button", { name });
|
||||
};
|
||||
const queryAllAliasButtons = (name: string) => {
|
||||
const dialog = screen.queryByRole("dialog");
|
||||
const scope = dialog ? within(dialog) : screen;
|
||||
return scope.queryAllByRole("button", { name });
|
||||
};
|
||||
|
||||
describe("PaginatedKeyAliasSelect", () => {
|
||||
const mockOnChange = vi.fn();
|
||||
|
||||
|
|
@ -72,25 +85,26 @@ describe("PaginatedKeyAliasSelect", () => {
|
|||
});
|
||||
|
||||
it("should display alias options when data is loaded", async () => {
|
||||
renderWithProviders(<PaginatedKeyAliasSelect onChange={mockOnChange} />);
|
||||
|
||||
const combobox = screen.getByRole("combobox");
|
||||
await userEvent.click(combobox);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByRole("option", { name: "alias-1" })).toBeInTheDocument();
|
||||
expect(screen.getByRole("option", { name: "alias-2" })).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
it("should call onChange when user selects an alias", async () => {
|
||||
const user = userEvent.setup({ delay: null });
|
||||
const user = userEvent.setup();
|
||||
renderWithProviders(<PaginatedKeyAliasSelect onChange={mockOnChange} />);
|
||||
|
||||
const combobox = screen.getByRole("combobox");
|
||||
await user.click(combobox);
|
||||
|
||||
const option = await screen.findByTitle("alias-1");
|
||||
await waitFor(() => {
|
||||
expect(getAliasButton("alias-1")).toBeInTheDocument();
|
||||
expect(getAliasButton("alias-2")).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
it("should call onChange when user selects an alias", async () => {
|
||||
const user = userEvent.setup();
|
||||
renderWithProviders(<PaginatedKeyAliasSelect onChange={mockOnChange} />);
|
||||
|
||||
const combobox = screen.getByRole("combobox");
|
||||
await user.click(combobox);
|
||||
|
||||
const option = await waitFor(() => getAliasButton("alias-1"));
|
||||
await user.click(option);
|
||||
|
||||
await waitFor(() => {
|
||||
|
|
@ -135,19 +149,19 @@ describe("PaginatedKeyAliasSelect", () => {
|
|||
isFetchingNextPage: false,
|
||||
} as any);
|
||||
|
||||
const user = userEvent.setup();
|
||||
renderWithProviders(<PaginatedKeyAliasSelect onChange={mockOnChange} />);
|
||||
|
||||
const combobox = screen.getByRole("combobox");
|
||||
await userEvent.click(combobox);
|
||||
await user.click(combobox);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByRole("option", { name: "alias-1" })).toBeInTheDocument();
|
||||
expect(getAliasButton("alias-1")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
const scrollableContainer = document.querySelector(
|
||||
".ant-select-dropdown .rc-virtual-list-holder",
|
||||
);
|
||||
expect(scrollableContainer).toBeInTheDocument();
|
||||
// The scrollable area wraps the option buttons inside the popover content.
|
||||
const scrollableContainer = getAliasButton("alias-1").parentElement;
|
||||
expect(scrollableContainer).toHaveClass("overflow-y-auto");
|
||||
});
|
||||
|
||||
it("should deduplicate aliases with the same value across pages", async () => {
|
||||
|
|
@ -166,13 +180,14 @@ describe("PaginatedKeyAliasSelect", () => {
|
|||
},
|
||||
} as any);
|
||||
|
||||
const user = userEvent.setup();
|
||||
renderWithProviders(<PaginatedKeyAliasSelect onChange={mockOnChange} />);
|
||||
|
||||
const combobox = screen.getByRole("combobox");
|
||||
await userEvent.click(combobox);
|
||||
await user.click(combobox);
|
||||
|
||||
await waitFor(() => {
|
||||
const options = screen.queryAllByRole("option", { name: "alias-1" });
|
||||
const options = queryAllAliasButtons("alias-1");
|
||||
expect(options.length).toBe(1);
|
||||
});
|
||||
});
|
||||
|
|
@ -193,16 +208,20 @@ describe("PaginatedKeyAliasSelect", () => {
|
|||
},
|
||||
} as any);
|
||||
|
||||
const user = userEvent.setup();
|
||||
renderWithProviders(<PaginatedKeyAliasSelect onChange={mockOnChange} />);
|
||||
|
||||
const combobox = screen.getByRole("combobox");
|
||||
await userEvent.click(combobox);
|
||||
await user.click(combobox);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByRole("option", { name: "valid-alias" })).toBeInTheDocument();
|
||||
const allOptions = screen.queryAllByRole("option");
|
||||
expect(allOptions.length).toBe(1);
|
||||
expect(getAliasButton("valid-alias")).toBeInTheDocument();
|
||||
});
|
||||
// Only the single valid-alias row is rendered inside the popover.
|
||||
const dialog = screen.getByRole("dialog");
|
||||
const rows = within(dialog).getAllByRole("button");
|
||||
// Rows = option button(s); the trigger button is outside the dialog.
|
||||
expect(rows.length).toBe(1);
|
||||
});
|
||||
|
||||
it("should respect allowClear prop", () => {
|
||||
|
|
@ -217,7 +236,7 @@ describe("PaginatedKeyAliasSelect", () => {
|
|||
renderWithProviders(<PaginatedKeyAliasSelect onChange={mockOnChange} disabled />);
|
||||
|
||||
const combobox = screen.getByRole("combobox");
|
||||
expect(combobox.closest(".ant-select")).toHaveClass("ant-select-disabled");
|
||||
expect(combobox).toBeDisabled();
|
||||
});
|
||||
|
||||
it("should not call fetchNextPage when hasNextPage is false", async () => {
|
||||
|
|
@ -226,12 +245,13 @@ describe("PaginatedKeyAliasSelect", () => {
|
|||
hasNextPage: false,
|
||||
} as any);
|
||||
|
||||
const user = userEvent.setup();
|
||||
renderWithProviders(<PaginatedKeyAliasSelect onChange={mockOnChange} />);
|
||||
|
||||
await userEvent.click(screen.getByRole("combobox"));
|
||||
await user.click(screen.getByRole("combobox"));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByRole("option", { name: "alias-1" })).toBeInTheDocument();
|
||||
expect(getAliasButton("alias-1")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
expect(mockFetchNextPage).not.toHaveBeenCalled();
|
||||
|
|
@ -243,10 +263,11 @@ describe("PaginatedKeyAliasSelect", () => {
|
|||
data: mockEmptyPages,
|
||||
} as any);
|
||||
|
||||
const user = userEvent.setup();
|
||||
renderWithProviders(<PaginatedKeyAliasSelect onChange={mockOnChange} />);
|
||||
|
||||
const combobox = screen.getByRole("combobox");
|
||||
await userEvent.click(combobox);
|
||||
await user.click(combobox);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText("No key aliases found")).toBeInTheDocument();
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { screen, waitFor } from "@testing-library/react";
|
||||
import { screen, waitFor, within } from "@testing-library/react";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { renderWithProviders } from "../../../../tests/test-utils";
|
||||
|
|
@ -43,6 +43,24 @@ const mockEmptyPages = {
|
|||
pages: [{ data: [], total_count: 0, current_page: 1, total_pages: 1, size: 50 }],
|
||||
};
|
||||
|
||||
// The popover renders each option as a <button> containing the model name
|
||||
// and model ID as separate text nodes. Because these are not role="option",
|
||||
// we locate them via the visible "Model ID: <id>" label.
|
||||
const getModelOption = (modelId: string) => {
|
||||
const dialog = screen.queryByRole("dialog");
|
||||
const scope = dialog ? within(dialog) : screen;
|
||||
const idText = scope.getByText(`Model ID: ${modelId}`);
|
||||
const btn = idText.closest("button");
|
||||
if (!btn) throw new Error(`No button for model ${modelId}`);
|
||||
return btn;
|
||||
};
|
||||
const queryModelOption = (modelId: string) => {
|
||||
const dialog = screen.queryByRole("dialog");
|
||||
const scope = dialog ? within(dialog) : screen;
|
||||
const idText = scope.queryByText(`Model ID: ${modelId}`);
|
||||
return idText ? idText.closest("button") : null;
|
||||
};
|
||||
|
||||
describe("PaginatedModelSelect", () => {
|
||||
const mockOnChange = vi.fn();
|
||||
|
||||
|
|
@ -75,26 +93,30 @@ describe("PaginatedModelSelect", () => {
|
|||
});
|
||||
|
||||
it("should display model options when data is loaded", async () => {
|
||||
renderWithProviders(<PaginatedModelSelect onChange={mockOnChange} />);
|
||||
|
||||
const combobox = screen.getByRole("combobox");
|
||||
await userEvent.click(combobox);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByRole("option", { name: "GPT-4 (model-1)" })).toBeInTheDocument();
|
||||
expect(screen.getByRole("option", { name: "Claude-3 (model-2)" })).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
it("should call onChange when user selects a model", async () => {
|
||||
const user = userEvent.setup({ delay: null });
|
||||
const user = userEvent.setup();
|
||||
renderWithProviders(<PaginatedModelSelect onChange={mockOnChange} />);
|
||||
|
||||
const combobox = screen.getByRole("combobox");
|
||||
await user.click(combobox);
|
||||
|
||||
const visibleOption = await screen.findByTitle("GPT-4 (model-1)");
|
||||
await user.click(visibleOption);
|
||||
await waitFor(() => {
|
||||
expect(getModelOption("model-1")).toBeInTheDocument();
|
||||
expect(getModelOption("model-2")).toBeInTheDocument();
|
||||
});
|
||||
const dialog = screen.getByRole("dialog");
|
||||
expect(within(dialog).getByText("GPT-4")).toBeInTheDocument();
|
||||
expect(within(dialog).getByText("Claude-3")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("should call onChange when user selects a model", async () => {
|
||||
const user = userEvent.setup();
|
||||
renderWithProviders(<PaginatedModelSelect onChange={mockOnChange} />);
|
||||
|
||||
const combobox = screen.getByRole("combobox");
|
||||
await user.click(combobox);
|
||||
|
||||
const option = await waitFor(() => getModelOption("model-1"));
|
||||
await user.click(option);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockOnChange).toHaveBeenCalledWith("model-1");
|
||||
|
|
@ -102,15 +124,16 @@ describe("PaginatedModelSelect", () => {
|
|||
});
|
||||
|
||||
it("should display selected value when value prop is provided", async () => {
|
||||
const user = userEvent.setup();
|
||||
renderWithProviders(
|
||||
<PaginatedModelSelect value="model-1" onChange={mockOnChange} />,
|
||||
);
|
||||
|
||||
const combobox = screen.getByRole("combobox");
|
||||
await userEvent.click(combobox);
|
||||
await user.click(combobox);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByRole("option", { name: "GPT-4 (model-1)" })).toBeInTheDocument();
|
||||
expect(getModelOption("model-1")).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -151,20 +174,20 @@ describe("PaginatedModelSelect", () => {
|
|||
isFetchingNextPage: false,
|
||||
} as any);
|
||||
|
||||
const user = userEvent.setup();
|
||||
renderWithProviders(<PaginatedModelSelect onChange={mockOnChange} />);
|
||||
|
||||
const combobox = screen.getByRole("combobox");
|
||||
await userEvent.click(combobox);
|
||||
await user.click(combobox);
|
||||
|
||||
let option: HTMLElement | null = null;
|
||||
await waitFor(() => {
|
||||
expect(screen.getByRole("option", { name: "GPT-4 (model-1)" })).toBeInTheDocument();
|
||||
option = getModelOption("model-1");
|
||||
expect(option).toBeInTheDocument();
|
||||
});
|
||||
|
||||
const scrollableContainer = document.querySelector(
|
||||
".ant-select-dropdown .rc-virtual-list-holder",
|
||||
);
|
||||
expect(scrollableContainer).toBeInTheDocument();
|
||||
expect(scrollableContainer).toHaveAttribute("style");
|
||||
const scrollableContainer = option!.parentElement;
|
||||
expect(scrollableContainer).toHaveClass("overflow-y-auto");
|
||||
});
|
||||
|
||||
it("should deduplicate models with same id across pages", async () => {
|
||||
|
|
@ -190,14 +213,16 @@ describe("PaginatedModelSelect", () => {
|
|||
isLoading: false,
|
||||
} as any);
|
||||
|
||||
const user = userEvent.setup();
|
||||
renderWithProviders(<PaginatedModelSelect onChange={mockOnChange} />);
|
||||
|
||||
const combobox = screen.getByRole("combobox");
|
||||
await userEvent.click(combobox);
|
||||
await user.click(combobox);
|
||||
|
||||
await waitFor(() => {
|
||||
const model1Options = screen.queryAllByRole("option", { name: /model-1/ });
|
||||
expect(model1Options.length).toBe(1);
|
||||
const dialog = screen.getByRole("dialog");
|
||||
const matches = within(dialog).queryAllByText("Model ID: model-1");
|
||||
expect(matches.length).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -225,16 +250,18 @@ describe("PaginatedModelSelect", () => {
|
|||
isLoading: false,
|
||||
} as any);
|
||||
|
||||
const user = userEvent.setup();
|
||||
renderWithProviders(<PaginatedModelSelect onChange={mockOnChange} />);
|
||||
|
||||
const combobox = screen.getByRole("combobox");
|
||||
await userEvent.click(combobox);
|
||||
await user.click(combobox);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByRole("option", { name: "Valid Model (valid-id)" })).toBeInTheDocument();
|
||||
expect(screen.queryByRole("option", { name: "No ID" })).not.toBeInTheDocument();
|
||||
expect(screen.queryByRole("option", { name: "Empty ID" })).not.toBeInTheDocument();
|
||||
expect(getModelOption("valid-id")).toBeInTheDocument();
|
||||
});
|
||||
const dialog = screen.getByRole("dialog");
|
||||
expect(within(dialog).queryByText("No ID")).not.toBeInTheDocument();
|
||||
expect(within(dialog).queryByText("Empty ID")).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("should show model ID only when model_name is empty", async () => {
|
||||
|
|
@ -257,14 +284,18 @@ describe("PaginatedModelSelect", () => {
|
|||
isLoading: false,
|
||||
} as any);
|
||||
|
||||
const user = userEvent.setup();
|
||||
renderWithProviders(<PaginatedModelSelect onChange={mockOnChange} />);
|
||||
|
||||
const combobox = screen.getByRole("combobox");
|
||||
await userEvent.click(combobox);
|
||||
await user.click(combobox);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByRole("option", { name: "id-only" })).toBeInTheDocument();
|
||||
expect(getModelOption("id-only")).toBeInTheDocument();
|
||||
});
|
||||
// No "Model name:" label is shown when model_name is empty.
|
||||
const dialog = screen.getByRole("dialog");
|
||||
expect(within(dialog).queryByText("Model name:")).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("should respect allowClear prop", () => {
|
||||
|
|
@ -279,7 +310,7 @@ describe("PaginatedModelSelect", () => {
|
|||
renderWithProviders(<PaginatedModelSelect onChange={mockOnChange} disabled />);
|
||||
|
||||
const combobox = screen.getByRole("combobox");
|
||||
expect(combobox.closest(".ant-select")).toHaveClass("ant-select-disabled");
|
||||
expect(combobox).toBeDisabled();
|
||||
});
|
||||
|
||||
it("should not call fetchNextPage when hasNextPage is false", async () => {
|
||||
|
|
@ -288,12 +319,13 @@ describe("PaginatedModelSelect", () => {
|
|||
hasNextPage: false,
|
||||
} as any);
|
||||
|
||||
const user = userEvent.setup();
|
||||
renderWithProviders(<PaginatedModelSelect onChange={mockOnChange} />);
|
||||
|
||||
await userEvent.click(screen.getByRole("combobox"));
|
||||
await user.click(screen.getByRole("combobox"));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByRole("option", { name: "GPT-4 (model-1)" })).toBeInTheDocument();
|
||||
expect(getModelOption("model-1")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
expect(mockFetchNextPage).not.toHaveBeenCalled();
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue