From a3248c6be80e83d8c6e218edbed2e14d3f2608ff Mon Sep 17 00:00:00 2001 From: yuneng-jiang Date: Tue, 21 Jul 2026 16:56:40 -0700 Subject: [PATCH] fix(ui): restore guardrail_info_helpers exports in GuardrailsPanel test mock (#34197) The test replaced the whole ./guardrail_info_helpers module with a factory returning only getGuardrailLogoAndName, so guardrailLogoMap became undefined. guardrail_garden_data.ts indexes that map at module scope and is reachable from the panel via guardrail_garden.tsx, so the file failed to collect and the suite never ran. Spread the real module and override only the stubbed function. Also cover the delete flow, which is the only consumer of the stubbed helper in this component; the mocked table already rendered a delete button that no test clicked. --- .../_components/GuardrailsPanel.test.tsx | 39 +++++++++++++++++-- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/GuardrailsPanel.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/GuardrailsPanel.test.tsx index 2ad332ae9ed..29655e5910a 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/GuardrailsPanel.test.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/GuardrailsPanel.test.tsx @@ -1,7 +1,7 @@ -import { render, screen, fireEvent } from "@testing-library/react"; +import { render, screen, fireEvent, waitFor, within } from "@testing-library/react"; import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import GuardrailsPanel from "./GuardrailsPanel"; -import { getGuardrailsList } from "@/components/networking"; +import { getGuardrailsList, deleteGuardrailCall } from "@/components/networking"; vi.mock("@/components/networking", () => ({ getGuardrailsList: vi.fn(), @@ -48,7 +48,8 @@ vi.mock("@/utils/roles", () => ({ isAdminRole: vi.fn((role: string) => role === "admin"), })); -vi.mock("./guardrail_info_helpers", () => ({ +vi.mock("./guardrail_info_helpers", async (importOriginal) => ({ + ...(await importOriginal()), getGuardrailLogoAndName: vi.fn(() => ({ logo: null, displayName: "Test Provider", @@ -78,6 +79,7 @@ describe("GuardrailsPanel", () => { }; const mockGetGuardrailsList = vi.mocked(getGuardrailsList); + const mockDeleteGuardrailCall = vi.mocked(deleteGuardrailCall); beforeEach(() => { vi.clearAllMocks(); @@ -107,4 +109,35 @@ describe("GuardrailsPanel", () => { fireEvent.click(screen.getByText("Guardrails")); expect(screen.getByText("Add New Guardrail")).toBeInTheDocument(); }); + + it("should delete the clicked guardrail after confirming in the modal", async () => { + render(); + fireEvent.click(screen.getByText("Guardrails")); + + fireEvent.click(await screen.findByTestId("delete-button")); + + const modal = within(await screen.findByRole("dialog")); + expect(modal.getByText("Delete Guardrail")).toBeInTheDocument(); + expect(modal.getByText("test-guardrail-1")).toBeInTheDocument(); + expect(modal.getByText("Test Provider")).toBeInTheDocument(); + + fireEvent.click(modal.getByRole("button", { name: "Delete" })); + + await waitFor(() => { + expect(mockDeleteGuardrailCall).toHaveBeenCalledWith("test-token", "test-guardrail-1"); + }); + expect(mockGetGuardrailsList).toHaveBeenCalledTimes(2); + }); + + it("should not delete anything when the modal is cancelled", async () => { + render(); + fireEvent.click(screen.getByText("Guardrails")); + + fireEvent.click(await screen.findByTestId("delete-button")); + const modal = within(await screen.findByRole("dialog")); + + fireEvent.click(modal.getByRole("button", { name: "Cancel" })); + + expect(mockDeleteGuardrailCall).not.toHaveBeenCalled(); + }); });