diff --git a/ui/litellm-dashboard/src/components/Navbar/WorkerDropdown/WorkerDropdown.test.tsx b/ui/litellm-dashboard/src/components/Navbar/WorkerDropdown/WorkerDropdown.test.tsx
index 17b8b393607..b6ad1cdc790 100644
--- a/ui/litellm-dashboard/src/components/Navbar/WorkerDropdown/WorkerDropdown.test.tsx
+++ b/ui/litellm-dashboard/src/components/Navbar/WorkerDropdown/WorkerDropdown.test.tsx
@@ -1,35 +1,12 @@
import { render, screen } from "@testing-library/react";
+import userEvent from "@testing-library/user-event";
import { describe, expect, it, vi, beforeEach } from "vitest";
-// Mock the useWorker hook
const mockUseWorker = vi.fn();
vi.mock("@/hooks/useWorker", () => ({
useWorker: () => mockUseWorker(),
}));
-// Mock antd Select
-vi.mock("antd", () => ({
- Select: ({ value, options, onChange, style, disabled, ...props }: any) => (
-
- ),
-}));
-
-// Mock icon
-vi.mock("@ant-design/icons", () => ({
- CloudServerOutlined: () => ,
-}));
-
import WorkerDropdown from "./WorkerDropdown";
describe("WorkerDropdown", () => {
@@ -44,7 +21,7 @@ describe("WorkerDropdown", () => {
vi.clearAllMocks();
});
- it("renders null when isControlPlane is false", () => {
+ it("should render nothing when isControlPlane is false", () => {
mockUseWorker.mockReturnValue({
isControlPlane: false,
selectedWorker: workers[0],
@@ -55,7 +32,7 @@ describe("WorkerDropdown", () => {
expect(container).toBeEmptyDOMElement();
});
- it("renders null when selectedWorker is null", () => {
+ it("should render nothing when selectedWorker is null", () => {
mockUseWorker.mockReturnValue({
isControlPlane: true,
selectedWorker: null,
@@ -66,7 +43,7 @@ describe("WorkerDropdown", () => {
expect(container).toBeEmptyDOMElement();
});
- it("renders the select when isControlPlane and selectedWorker exist", () => {
+ it("should render the select trigger when isControlPlane and selectedWorker exist", () => {
mockUseWorker.mockReturnValue({
isControlPlane: true,
selectedWorker: workers[0],
@@ -74,23 +51,10 @@ describe("WorkerDropdown", () => {
});
render();
- expect(screen.getByTestId("worker-select")).toBeInTheDocument();
+ expect(screen.getByRole("combobox")).toBeInTheDocument();
});
- it("renders all worker options", () => {
- mockUseWorker.mockReturnValue({
- isControlPlane: true,
- selectedWorker: workers[0],
- workers,
- });
-
- render();
- expect(screen.getByText("Worker 1")).toBeInTheDocument();
- expect(screen.getByText("Worker 2")).toBeInTheDocument();
- expect(screen.getByText("Worker 3")).toBeInTheDocument();
- });
-
- it("sets current worker as selected value", () => {
+ it("should display the currently selected worker name in the trigger", () => {
mockUseWorker.mockReturnValue({
isControlPlane: true,
selectedWorker: workers[1],
@@ -98,36 +62,53 @@ describe("WorkerDropdown", () => {
});
render();
- const select = screen.getByTestId("worker-select") as HTMLSelectElement;
- expect(select.value).toBe("w2");
+ expect(screen.getByRole("combobox")).toHaveTextContent("Worker 2");
});
- it("disables the currently selected worker in options", () => {
+ it("should render all worker options when opened", async () => {
mockUseWorker.mockReturnValue({
isControlPlane: true,
selectedWorker: workers[0],
workers,
});
- render();
- const options = screen.getAllByRole("option");
- const selectedOption = options.find((opt) => (opt as HTMLOptionElement).value === "w1");
- expect(selectedOption).toBeDisabled();
- });
-
- it("calls onWorkerSwitch when selection changes", async () => {
- mockUseWorker.mockReturnValue({
- isControlPlane: true,
- selectedWorker: workers[0],
- workers,
- });
-
- render();
- const select = screen.getByTestId("worker-select");
-
- const { default: userEvent } = await import("@testing-library/user-event");
const user = userEvent.setup();
- await user.selectOptions(select, "w2");
+ render();
+ await user.click(screen.getByRole("combobox"));
+
+ expect(await screen.findByRole("option", { name: "Worker 1" })).toBeInTheDocument();
+ expect(screen.getByRole("option", { name: "Worker 2" })).toBeInTheDocument();
+ expect(screen.getByRole("option", { name: "Worker 3" })).toBeInTheDocument();
+ });
+
+ it("should disable the currently selected worker in the options list", async () => {
+ mockUseWorker.mockReturnValue({
+ isControlPlane: true,
+ selectedWorker: workers[0],
+ workers,
+ });
+
+ const user = userEvent.setup();
+ render();
+ await user.click(screen.getByRole("combobox"));
+
+ const selectedOption = await screen.findByRole("option", { name: "Worker 1" });
+ expect(selectedOption).toHaveAttribute("data-disabled");
+ });
+
+ it("should call onWorkerSwitch when a different worker is picked", async () => {
+ mockUseWorker.mockReturnValue({
+ isControlPlane: true,
+ selectedWorker: workers[0],
+ workers,
+ });
+
+ const user = userEvent.setup();
+ render();
+ await user.click(screen.getByRole("combobox"));
+
+ const option = await screen.findByRole("option", { name: "Worker 2" });
+ await user.click(option);
expect(mockOnWorkerSwitch).toHaveBeenCalledWith("w2");
});
diff --git a/ui/litellm-dashboard/src/components/UsagePage/components/UsagePageView.test.tsx b/ui/litellm-dashboard/src/components/UsagePage/components/UsagePageView.test.tsx
index bbcddd572cd..9ee10c54010 100644
--- a/ui/litellm-dashboard/src/components/UsagePage/components/UsagePageView.test.tsx
+++ b/ui/litellm-dashboard/src/components/UsagePage/components/UsagePageView.test.tsx
@@ -225,37 +225,6 @@ vi.mock("antd", async (importOriginal) => {
};
});
-vi.mock("@ant-design/icons", async () => {
- const React = await import("react");
-
- function Icon() {
- return React.createElement("span");
- }
-
- function LoadingOutlined(props: any) {
- return React.createElement("span", { "data-testid": "loading-icon", ...props });
- }
-
- return {
- GlobalOutlined: Icon,
- BankOutlined: Icon,
- TeamOutlined: Icon,
- ShoppingCartOutlined: Icon,
- TagsOutlined: Icon,
- RobotOutlined: Icon,
- LineChartOutlined: Icon,
- BarChartOutlined: Icon,
- ClockCircleOutlined: Icon,
- CalendarOutlined: Icon,
- InfoCircleOutlined: Icon,
- UserOutlined: Icon,
- DownOutlined: Icon,
- RightOutlined: Icon,
- ExportOutlined: Icon,
- LoadingOutlined,
- };
-});
-
// Mock Tremor components
vi.mock("@tremor/react", async () => {
const React = await import("react");
diff --git a/ui/litellm-dashboard/src/components/atoms/Tooltip.test.tsx b/ui/litellm-dashboard/src/components/atoms/Tooltip.test.tsx
index 8242a4506fa..bb7ecaa2afc 100644
--- a/ui/litellm-dashboard/src/components/atoms/Tooltip.test.tsx
+++ b/ui/litellm-dashboard/src/components/atoms/Tooltip.test.tsx
@@ -1,41 +1,49 @@
-import { describe, it, expect, vi } from "vitest";
+import { describe, it, expect } from "vitest";
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { Tooltip } from "./Tooltip";
-vi.mock("@ant-design/icons", () => ({
- QuestionCircleOutlined: (props: any) => ,
-}));
+const getTriggerIcon = (container: HTMLElement) => {
+ const svg = container.querySelector("svg.lucide-circle-help, svg.lucide-help-circle");
+ if (!svg) throw new Error("Default HelpCircle icon not rendered");
+ return svg as SVGElement;
+};
describe("Tooltip", () => {
it("should render", () => {
- render();
- expect(screen.getByTestId("question-icon")).toBeInTheDocument();
+ const { container } = render();
+ expect(getTriggerIcon(container)).toBeInTheDocument();
});
it("should render children instead of the default icon when provided", () => {
- render();
+ const { container } = render(
+
+
+ ,
+ );
expect(screen.getByRole("button", { name: /info/i })).toBeInTheDocument();
- expect(screen.queryByTestId("question-icon")).not.toBeInTheDocument();
+ expect(
+ container.querySelector("svg.lucide-circle-help, svg.lucide-help-circle"),
+ ).not.toBeInTheDocument();
});
it("should show tooltip content on mouse enter", async () => {
const user = userEvent.setup();
- render();
+ const { container } = render();
- await user.hover(screen.getByTestId("question-icon"));
+ await user.hover(getTriggerIcon(container));
expect(screen.getByText("Help text")).toBeInTheDocument();
});
it("should hide tooltip content on mouse leave", async () => {
const user = userEvent.setup();
- render();
+ const { container } = render();
- await user.hover(screen.getByTestId("question-icon"));
+ await user.hover(getTriggerIcon(container));
expect(screen.getByText("Help text")).toBeInTheDocument();
- await user.unhover(screen.getByTestId("question-icon"));
+ await user.unhover(getTriggerIcon(container));
expect(screen.queryByText("Help text")).not.toBeInTheDocument();
});
diff --git a/ui/litellm-dashboard/src/components/common_components/KeyLifecycleSettings.test.tsx b/ui/litellm-dashboard/src/components/common_components/KeyLifecycleSettings.test.tsx
index 462b0a3d99d..aa2f8f27403 100644
--- a/ui/litellm-dashboard/src/components/common_components/KeyLifecycleSettings.test.tsx
+++ b/ui/litellm-dashboard/src/components/common_components/KeyLifecycleSettings.test.tsx
@@ -37,10 +37,6 @@ vi.mock("antd", () => {
};
});
-vi.mock("@ant-design/icons", () => ({
- InfoCircleOutlined: () => ℹ,
-}));
-
vi.mock("@tremor/react", () => ({
TextInput: ({ value, onValueChange, onChange, placeholder, name, className }: any) => {
const handleChange = (e: React.ChangeEvent) => {
diff --git a/ui/litellm-dashboard/src/components/guardrails/guardrail_garden_card.test.tsx b/ui/litellm-dashboard/src/components/guardrails/guardrail_garden_card.test.tsx
index 0fa5d2ffcd2..901a9cc4d1a 100644
--- a/ui/litellm-dashboard/src/components/guardrails/guardrail_garden_card.test.tsx
+++ b/ui/litellm-dashboard/src/components/guardrails/guardrail_garden_card.test.tsx
@@ -4,10 +4,6 @@ import userEvent from "@testing-library/user-event";
import GuardrailCard from "./guardrail_garden_card";
import type { GuardrailCardInfo } from "./guardrail_garden_data";
-vi.mock("@ant-design/icons", () => ({
- CheckCircleFilled: ({ style, ...props }: any) => ,
-}));
-
const baseCard: GuardrailCardInfo = {
id: "test-guard",
name: "Test Guardrail",
diff --git a/ui/litellm-dashboard/src/components/organisms/create_key_button.test.tsx b/ui/litellm-dashboard/src/components/organisms/create_key_button.test.tsx
index 3ad59cb3693..3e819f7bd87 100644
--- a/ui/litellm-dashboard/src/components/organisms/create_key_button.test.tsx
+++ b/ui/litellm-dashboard/src/components/organisms/create_key_button.test.tsx
@@ -50,10 +50,6 @@ vi.mock("@/app/(dashboard)/hooks/keys/useKeys", () => ({
},
}));
-vi.mock("@ant-design/icons", () => ({
- InfoCircleOutlined: () => null,
-}));
-
vi.mock("react-copy-to-clipboard", () => ({
CopyToClipboard: ({ children }: { children: any }) => children,
}));
diff --git a/ui/litellm-dashboard/src/components/ui/AntDLoadingSpinner.test.tsx b/ui/litellm-dashboard/src/components/ui/AntDLoadingSpinner.test.tsx
index e86a7659855..a9af832968b 100644
--- a/ui/litellm-dashboard/src/components/ui/AntDLoadingSpinner.test.tsx
+++ b/ui/litellm-dashboard/src/components/ui/AntDLoadingSpinner.test.tsx
@@ -1,61 +1,43 @@
-import { render, screen } from "@testing-library/react";
-import { describe, expect, it, vi } from "vitest";
-
-// Mock antd Spin component
-vi.mock("antd", () => ({
- Spin: ({ indicator, size, ...props }: any) => (
-
- {indicator}
-
- ),
-}));
-
-// Mock the icon
-vi.mock("@ant-design/icons", () => ({
- LoadingOutlined: ({ style, spin, ...props }: any) => (
-
- ),
-}));
+import { render } from "@testing-library/react";
+import { describe, expect, it } from "vitest";
import { AntDLoadingSpinner } from "./AntDLoadingSpinner";
describe("AntDLoadingSpinner", () => {
- it("renders without props", () => {
- render();
- expect(screen.getByTestId("spin")).toBeInTheDocument();
- expect(screen.getByTestId("loading-icon")).toBeInTheDocument();
+ it("should render a lucide spinner svg", () => {
+ const { container } = render();
+ const svg = container.querySelector("svg");
+ expect(svg).toBeInTheDocument();
+ expect(svg).toHaveClass("animate-spin");
});
- it("passes size prop to Spin", () => {
- render();
- expect(screen.getByTestId("spin")).toHaveAttribute("data-size", "large");
+ it("should use large size class when size=large", () => {
+ const { container } = render();
+ const svg = container.querySelector("svg");
+ expect(svg).toHaveClass("h-6", "w-6");
});
- it("passes small size to Spin", () => {
- render();
- expect(screen.getByTestId("spin")).toHaveAttribute("data-size", "small");
+ it("should use small size class when size=small", () => {
+ const { container } = render();
+ const svg = container.querySelector("svg");
+ expect(svg).toHaveClass("h-3", "w-3");
});
- it("applies custom fontSize to the icon", () => {
- render();
- const icon = screen.getByTestId("loading-icon");
- expect(icon).toHaveStyle({ fontSize: "32px" });
+ it("should default to size 4 when no size prop is provided", () => {
+ const { container } = render();
+ const svg = container.querySelector("svg");
+ expect(svg).toHaveClass("h-4", "w-4");
});
- it("does not set style when fontSize is not provided", () => {
- render();
- const icon = screen.getByTestId("loading-icon");
- expect(icon.style.fontSize).toBe("");
+ it("should apply custom fontSize to the svg style", () => {
+ const { container } = render();
+ const svg = container.querySelector("svg");
+ expect(svg).toHaveStyle({ fontSize: "32px" });
});
- it("sets spin attribute on icon", () => {
- render();
- const icon = screen.getByTestId("loading-icon");
- expect(icon).toHaveAttribute("data-spin", "true");
+ it("should not set an inline fontSize when not provided", () => {
+ const { container } = render();
+ const svg = container.querySelector("svg") as SVGElement;
+ expect(svg.style.fontSize).toBe("");
});
});