diff --git a/ui/litellm-dashboard/src/components/policies/attachment_table.test.tsx b/ui/litellm-dashboard/src/components/policies/attachment_table.test.tsx
index 4372983b71a..01caa373ac3 100644
--- a/ui/litellm-dashboard/src/components/policies/attachment_table.test.tsx
+++ b/ui/litellm-dashboard/src/components/policies/attachment_table.test.tsx
@@ -10,35 +10,6 @@ vi.mock("./impact_popover", () => ({
default: () => ,
}));
-vi.mock("@heroicons/react/outline", () => ({
- TrashIcon: function TrashIcon() { return null; },
- SwitchVerticalIcon: function SwitchVerticalIcon() { return null; },
- ChevronUpIcon: function ChevronUpIcon() { return null; },
- ChevronDownIcon: function ChevronDownIcon() { return null; },
-}));
-
-vi.mock("@tremor/react", async (importOriginal) => {
- const actual = await importOriginal();
- return {
- ...actual,
- Button: React.forwardRef(({ children, ...props }, ref) =>
- React.createElement("button", { ...props, ref }, children)
- ),
- Tooltip: ({ children }: { children?: React.ReactNode }) =>
- React.createElement(React.Fragment, null, children),
- Switch: ({ checked, onChange, className }: { checked?: boolean; onChange?: (v: boolean) => void; className?: string }) =>
- React.createElement("input", {
- type: "checkbox",
- role: "switch",
- checked,
- onChange: (e: React.ChangeEvent) => onChange?.(e.target.checked),
- className,
- }),
- Icon: ({ icon: IconComp, onClick, className }: any) =>
- React.createElement("button", { type: "button", onClick, className }, IconComp?.displayName ?? IconComp?.name ?? "icon"),
- };
-});
-
const makeAttachment = (overrides: Partial = {}): PolicyAttachment => ({
attachment_id: "att-abcdef1",
policy_name: "my-policy",
@@ -111,14 +82,14 @@ describe("AttachmentTable", () => {
const attachment = makeAttachment({ attachment_id: "att-del-me1" });
const user = userEvent.setup();
renderWithProviders();
- await user.click(screen.getByRole("button", { name: /TrashIcon/i }));
+ await user.click(screen.getByRole("button", { name: /delete attachment/i }));
expect(defaultProps.onDeleteClick).toHaveBeenCalledWith("att-del-me1");
});
it("should not show the delete icon for non-admins", () => {
const attachment = makeAttachment();
renderWithProviders();
- expect(screen.queryByRole("button", { name: /TrashIcon/i })).not.toBeInTheDocument();
+ expect(screen.queryByRole("button", { name: /delete attachment/i })).not.toBeInTheDocument();
});
it("should show a truncated attachment ID in the table", () => {
diff --git a/ui/litellm-dashboard/src/components/policies/impact_popover.test.tsx b/ui/litellm-dashboard/src/components/policies/impact_popover.test.tsx
index b8758927794..b420385b0b2 100644
--- a/ui/litellm-dashboard/src/components/policies/impact_popover.test.tsx
+++ b/ui/litellm-dashboard/src/components/policies/impact_popover.test.tsx
@@ -9,42 +9,31 @@ import { PolicyAttachment } from "./types";
vi.mock("../networking");
-vi.mock("@heroicons/react/outline", () => ({
- EyeIcon: function EyeIcon() { return null; },
-}));
-
-vi.mock("@tremor/react", async (importOriginal) => {
- const actual = await importOriginal();
- return {
- ...actual,
- Icon: ({ icon: IconComp, onClick, className }: any) =>
- React.createElement("button", { type: "button", onClick, className }, IconComp?.displayName ?? IconComp?.name ?? "icon"),
- };
-});
-
// Expose the Popover's onOpenChange so tests can trigger it programmatically.
-vi.mock("antd", async (importOriginal) => {
- const actual = await importOriginal();
+// The source uses shadcn Popover (Radix UI) which renders content in a portal
+// only when open; replace it with a simple inline renderer so test assertions
+// can reach popover content without having to wait for Radix animations.
+vi.mock("@/components/ui/popover", () => {
+ const PopoverContext = React.createContext<{
+ onOpenChange?: (open: boolean) => void;
+ }>({});
return {
- ...actual,
- Popover: ({ children, onOpenChange, content }: any) =>
+ Popover: ({ children, onOpenChange }: any) =>
React.createElement(
- "div",
- null,
- React.createElement("div", { "data-testid": "popover-content" }, content),
- React.createElement(
- "div",
- {
- role: "button",
- "aria-label": "open-popover",
- onClick: () => onOpenChange?.(true),
- },
- children
- )
+ PopoverContext.Provider,
+ { value: { onOpenChange } },
+ children,
),
- Tooltip: ({ children }: any) => React.createElement(React.Fragment, null, children),
- Spin: () => React.createElement("span", null, "Loading..."),
- Tag: ({ children }: any) => React.createElement("span", null, children),
+ PopoverTrigger: ({ children }: any) => {
+ const ctx = React.useContext(PopoverContext);
+ return React.cloneElement(children, {
+ "aria-label": "open-popover",
+ role: "button",
+ onClick: () => ctx.onOpenChange?.(true),
+ });
+ },
+ PopoverContent: ({ children }: any) =>
+ React.createElement("div", { "data-testid": "popover-content" }, children),
};
});
diff --git a/ui/litellm-dashboard/src/components/policies/index.test.tsx b/ui/litellm-dashboard/src/components/policies/index.test.tsx
index 4a33e8905a5..3d7db6bd820 100644
--- a/ui/litellm-dashboard/src/components/policies/index.test.tsx
+++ b/ui/litellm-dashboard/src/components/policies/index.test.tsx
@@ -56,55 +56,6 @@ vi.mock("./impact_popover", () => ({
default: () => ,
}));
-vi.mock("@heroicons/react/outline", () => ({
- TrashIcon: function TrashIcon() {
- return null;
- },
- SwitchVerticalIcon: function SwitchVerticalIcon() {
- return null;
- },
- ChevronUpIcon: function ChevronUpIcon() {
- return null;
- },
- ChevronDownIcon: function ChevronDownIcon() {
- return null;
- },
-}));
-
-vi.mock("@tremor/react", async (importOriginal) => {
- const actual = await importOriginal();
- return {
- ...actual,
- Button: React.forwardRef(({ children, ...props }, ref) =>
- React.createElement("button", { ...props, ref }, children),
- ),
- Tooltip: ({ children }: { children?: React.ReactNode }) =>
- React.createElement(React.Fragment, null, children),
- Switch: ({
- checked,
- onChange,
- className,
- }: {
- checked?: boolean;
- onChange?: (v: boolean) => void;
- className?: string;
- }) =>
- React.createElement("input", {
- type: "checkbox",
- role: "switch",
- checked,
- onChange: (e: React.ChangeEvent) => onChange?.(e.target.checked),
- className,
- }),
- Icon: ({ icon: _IconComp, onClick, className }: any) =>
- React.createElement(
- "button",
- { type: "button", onClick, className },
- "TrashIcon",
- ),
- };
-});
-
vi.mock("./policy_templates", () => ({
__esModule: true,
default: () => ,
@@ -168,9 +119,9 @@ describe("PoliciesPanel attachment delete", () => {
expect(screen.getByText("test-policy")).toBeInTheDocument();
});
- await user.click(screen.getByRole("button", { name: /TrashIcon/i }));
+ await user.click(screen.getByRole("button", { name: /delete attachment/i }));
- const dialog = await screen.findByRole("dialog", {}, { timeout: 5000 });
+ const dialog = await screen.findByRole("alertdialog", {}, { timeout: 5000 });
expect(
within(dialog).getByText(/Are you sure you want to delete this attachment/i),
).toBeInTheDocument();
@@ -202,8 +153,8 @@ describe("PoliciesPanel attachment delete", () => {
expect(screen.getByText("test-policy")).toBeInTheDocument();
});
- await user.click(screen.getByRole("button", { name: /TrashIcon/i }));
- const dialog = await screen.findByRole("dialog", {}, { timeout: 5000 });
+ await user.click(screen.getByRole("button", { name: /delete attachment/i }));
+ const dialog = await screen.findByRole("alertdialog", {}, { timeout: 5000 });
const deleteButton = within(dialog).getByRole("button", { name: /^delete$/i });
await user.click(deleteButton);
@@ -214,7 +165,7 @@ describe("PoliciesPanel attachment delete", () => {
resolveDelete?.();
await waitFor(() => {
- expect(screen.queryByRole("dialog")).not.toBeInTheDocument();
+ expect(screen.queryByRole("alertdialog")).not.toBeInTheDocument();
});
});
});
diff --git a/ui/litellm-dashboard/src/components/policies/policy_table.test.tsx b/ui/litellm-dashboard/src/components/policies/policy_table.test.tsx
index f671fae6b9b..fd92db966a1 100644
--- a/ui/litellm-dashboard/src/components/policies/policy_table.test.tsx
+++ b/ui/litellm-dashboard/src/components/policies/policy_table.test.tsx
@@ -6,30 +6,6 @@ import { beforeEach, describe, expect, it, vi } from "vitest";
import PolicyTable from "./policy_table";
import { Policy } from "./types";
-vi.mock("@heroicons/react/outline", () => ({
- TrashIcon: function TrashIcon() { return null; },
- PencilIcon: function PencilIcon() { return null; },
- SwitchVerticalIcon: function SwitchVerticalIcon() { return null; },
- ChevronUpIcon: function ChevronUpIcon() { return null; },
- ChevronDownIcon: function ChevronDownIcon() { return null; },
-}));
-
-vi.mock("@tremor/react", async (importOriginal) => {
- const actual = await importOriginal();
- return {
- ...actual,
- Button: React.forwardRef(({ children, ...props }, ref) =>
- React.createElement("button", { ...props, ref }, children)
- ),
- Icon: ({ icon: IconComp, onClick, className }: any) =>
- React.createElement("button", { type: "button", onClick, className }, IconComp?.displayName ?? IconComp?.name ?? "icon"),
- Tooltip: ({ children }: { children?: React.ReactNode }) =>
- React.createElement(React.Fragment, null, children),
- Badge: ({ children }: { children?: React.ReactNode }) =>
- React.createElement("span", null, children),
- };
-});
-
const makePolicy = (overrides: Partial = {}): Policy => ({
policy_id: "policy-id-1",
policy_name: "test-policy",
@@ -94,7 +70,7 @@ describe("PolicyTable", () => {
const user = userEvent.setup();
const policy = makePolicy({ policy_name: "del-policy", policy_id: "del-id-1" });
renderWithProviders();
- await user.click(screen.getByRole("button", { name: /TrashIcon/i }));
+ await user.click(screen.getByRole("button", { name: /delete policy/i }));
expect(defaultProps.onDeleteClick).toHaveBeenCalledWith("del-id-1", "del-policy");
});
@@ -102,15 +78,15 @@ describe("PolicyTable", () => {
const user = userEvent.setup();
const policy = makePolicy({ policy_name: "edit-policy", policy_id: "edit-id-1" });
renderWithProviders();
- await user.click(screen.getByRole("button", { name: /PencilIcon/i }));
+ await user.click(screen.getByRole("button", { name: /edit policy/i }));
expect(defaultProps.onEditClick).toHaveBeenCalledWith(policy);
});
it("should not show admin action icons for non-admins", () => {
const policy = makePolicy();
renderWithProviders();
- expect(screen.queryByRole("button", { name: /TrashIcon/i })).not.toBeInTheDocument();
- expect(screen.queryByRole("button", { name: /PencilIcon/i })).not.toBeInTheDocument();
+ expect(screen.queryByRole("button", { name: /delete policy/i })).not.toBeInTheDocument();
+ expect(screen.queryByRole("button", { name: /edit policy/i })).not.toBeInTheDocument();
});
it("should show a version badge when multiple versions of the same policy name exist", () => {
diff --git a/ui/litellm-dashboard/src/components/policies/policy_templates.test.tsx b/ui/litellm-dashboard/src/components/policies/policy_templates.test.tsx
index b53cab42208..4cfa2d86f45 100644
--- a/ui/litellm-dashboard/src/components/policies/policy_templates.test.tsx
+++ b/ui/litellm-dashboard/src/components/policies/policy_templates.test.tsx
@@ -8,14 +8,6 @@ import PolicyTemplates from "./policy_templates";
vi.mock("../networking");
-vi.mock("@heroicons/react/outline", () => ({
- ShieldCheckIcon: function ShieldCheckIcon() { return null; },
- ShieldExclamationIcon: function ShieldExclamationIcon() { return null; },
- BeakerIcon: function BeakerIcon() { return null; },
- CurrencyDollarIcon: function CurrencyDollarIcon() { return null; },
- CheckCircleIcon: function CheckCircleIcon() { return null; },
-}));
-
const makeTemplate = (overrides: any = {}) => ({
id: "tpl-1",
title: "Test Template",
diff --git a/ui/litellm-dashboard/src/components/templates/KeyInfoView.handleKeyUpdate.test.tsx b/ui/litellm-dashboard/src/components/templates/KeyInfoView.handleKeyUpdate.test.tsx
index abbc92f0210..c1c5761a1d1 100644
--- a/ui/litellm-dashboard/src/components/templates/KeyInfoView.handleKeyUpdate.test.tsx
+++ b/ui/litellm-dashboard/src/components/templates/KeyInfoView.handleKeyUpdate.test.tsx
@@ -164,37 +164,6 @@ vi.mock("antd", async (importOriginal) => {
return { ...actual, Form, Input, InputNumber, Select, Tooltip, Button };
});
-// Icons -> async factory & local React
-vi.mock("@heroicons/react/outline", async () => {
- const React = await import("react");
- function ArrowLeftIcon() {
- return React.createElement("span");
- }
- (ArrowLeftIcon as any).displayName = "ArrowLeftIcon";
- function TrashIcon() {
- return React.createElement("span");
- }
- (TrashIcon as any).displayName = "TrashIcon";
- function RefreshIcon() {
- return React.createElement("span");
- }
- (RefreshIcon as any).displayName = "RefreshIcon";
- return { ArrowLeftIcon, TrashIcon, RefreshIcon };
-});
-
-vi.mock("lucide-react", async () => {
- const React = await import("react");
- function CopyIcon() {
- return React.createElement("span");
- }
- (CopyIcon as any).displayName = "CopyIcon";
- function CheckIcon() {
- return React.createElement("span");
- }
- (CheckIcon as any).displayName = "CheckIcon";
- return { CopyIcon, CheckIcon };
-});
-
// Heavy children -> async factories & local React
vi.mock("../organisms/RegenerateKeyModal", async () => {
const React = await import("react");