diff --git a/ui/litellm-dashboard/src/components/router_settings/OptionalPreCallChecksSelector.test.tsx b/ui/litellm-dashboard/src/components/router_settings/OptionalPreCallChecksSelector.test.tsx new file mode 100644 index 00000000000..2e4b7712c5f --- /dev/null +++ b/ui/litellm-dashboard/src/components/router_settings/OptionalPreCallChecksSelector.test.tsx @@ -0,0 +1,101 @@ +import { describe, it, expect, vi } from "vitest"; +import { render, screen } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; +import OptionalPreCallChecksSelector from "./OptionalPreCallChecksSelector"; + +vi.mock("antd", async (importOriginal) => { + const actual = await importOriginal(); + return { + ...actual, + Select: ({ value, onChange, options, "data-testid": testId }: any) => ( + + ), + }; +}); + +const baseMetadata = { + optional_pre_call_checks: { + ui_field_name: "Optional Pre-call Checks", + field_description: "Extra checks the router runs before picking a deployment", + link: null, + }, +}; + +const options = ["prompt_caching", "router_budget_limiting", "session_affinity"]; + +describe("OptionalPreCallChecksSelector", () => { + it("should render one option per entry in options", () => { + render( + , + ); + const select = screen.getByTestId("optional-pre-call-checks-select") as HTMLSelectElement; + expect(Array.from(select.options).map((o) => o.value)).toEqual(options); + }); + + it("should display default label when no metadata is provided", () => { + render( + , + ); + expect(screen.getByText("Optional Pre-call Checks")).toBeInTheDocument(); + }); + + it("should display the label and description from metadata when provided", () => { + render( + , + ); + expect(screen.getByText("Extra checks the router runs before picking a deployment")).toBeInTheDocument(); + }); + + it("should render a Learn more link when metadata provides one", () => { + const metadata = { + optional_pre_call_checks: { ...baseMetadata.optional_pre_call_checks, link: "https://docs.example.com/checks" }, + }; + render( + , + ); + const link = screen.getByRole("link", { name: /learn more/i }); + expect(link).toHaveAttribute("href", "https://docs.example.com/checks"); + }); + + it("should call onChange with the selected checks", async () => { + const onChange = vi.fn(); + const user = userEvent.setup(); + render( + , + ); + + await user.selectOptions(screen.getByTestId("optional-pre-call-checks-select"), "prompt_caching"); + + expect(onChange).toHaveBeenCalledWith(["prompt_caching"]); + }); + + it("should reflect an already-selected value", () => { + render( + , + ); + const select = screen.getByTestId("optional-pre-call-checks-select") as HTMLSelectElement; + const selected = Array.from(select.selectedOptions).map((o) => o.value); + expect(selected).toEqual(["router_budget_limiting"]); + }); +}); diff --git a/ui/litellm-dashboard/src/components/router_settings/OptionalPreCallChecksSelector.tsx b/ui/litellm-dashboard/src/components/router_settings/OptionalPreCallChecksSelector.tsx new file mode 100644 index 00000000000..ab52bad644d --- /dev/null +++ b/ui/litellm-dashboard/src/components/router_settings/OptionalPreCallChecksSelector.tsx @@ -0,0 +1,55 @@ +import React from "react"; +import { Select } from "antd"; + +interface OptionalPreCallChecksSelectorProps { + value: string[]; + options: string[]; + routerFieldsMetadata: { [key: string]: any }; + onChange: (value: string[]) => void; +} + +const OptionalPreCallChecksSelector: React.FC = ({ + value, + options, + routerFieldsMetadata, + onChange, +}) => { + const meta = routerFieldsMetadata["optional_pre_call_checks"]; + + return ( +
+