mirror of
https://github.com/tiennm99/litellm.git
synced 2026-08-05 08:23:17 +00:00
Add unit tests for 5 untested UI components
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
56af724943
commit
4405837aaa
@@ -0,0 +1,46 @@
|
||||
import { describe, it, expect, vi } 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) => <span data-testid="question-icon" {...props} />,
|
||||
}));
|
||||
|
||||
describe("Tooltip", () => {
|
||||
it("should render", () => {
|
||||
render(<Tooltip content="Help text" />);
|
||||
expect(screen.getByTestId("question-icon")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("should render children instead of the default icon when provided", () => {
|
||||
render(<Tooltip content="Help text"><button>Info</button></Tooltip>);
|
||||
expect(screen.getByRole("button", { name: /info/i })).toBeInTheDocument();
|
||||
expect(screen.queryByTestId("question-icon")).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("should show tooltip content on mouse enter", async () => {
|
||||
const user = userEvent.setup();
|
||||
render(<Tooltip content="Help text" />);
|
||||
|
||||
await user.hover(screen.getByTestId("question-icon"));
|
||||
|
||||
expect(screen.getByText("Help text")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("should hide tooltip content on mouse leave", async () => {
|
||||
const user = userEvent.setup();
|
||||
render(<Tooltip content="Help text" />);
|
||||
|
||||
await user.hover(screen.getByTestId("question-icon"));
|
||||
expect(screen.getByText("Help text")).toBeInTheDocument();
|
||||
|
||||
await user.unhover(screen.getByTestId("question-icon"));
|
||||
expect(screen.queryByText("Help text")).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("should not show tooltip content before hovering", () => {
|
||||
render(<Tooltip content="Help text" />);
|
||||
expect(screen.queryByText("Help text")).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,27 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import { render, screen } from "@testing-library/react";
|
||||
import DefaultProxyAdminTag from "./DefaultProxyAdminTag";
|
||||
|
||||
describe("DefaultProxyAdminTag", () => {
|
||||
it("should render", () => {
|
||||
render(<DefaultProxyAdminTag userId="some-user" />);
|
||||
expect(screen.getByText("some-user")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("should render a blue tag when userId is default_user_id", () => {
|
||||
render(<DefaultProxyAdminTag userId="default_user_id" />);
|
||||
expect(screen.getByText("Default Proxy Admin")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("should render plain text when userId is a regular value", () => {
|
||||
render(<DefaultProxyAdminTag userId="alice@example.com" />);
|
||||
expect(screen.getByText("alice@example.com")).toBeInTheDocument();
|
||||
expect(screen.queryByText("Default Proxy Admin")).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("should render empty text when userId is null", () => {
|
||||
const { container } = render(<DefaultProxyAdminTag userId={null} />);
|
||||
expect(screen.queryByText("Default Proxy Admin")).not.toBeInTheDocument();
|
||||
expect(container.textContent).toBe("");
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,72 @@
|
||||
import { describe, it, expect, vi } from "vitest";
|
||||
import { render, screen, fireEvent, act } from "@testing-library/react";
|
||||
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) => <span data-testid="check-icon" {...props} />,
|
||||
}));
|
||||
|
||||
const baseCard: GuardrailCardInfo = {
|
||||
id: "test-guard",
|
||||
name: "Test Guardrail",
|
||||
description: "A guardrail for testing purposes",
|
||||
category: "litellm",
|
||||
logo: "/logos/test.svg",
|
||||
tags: ["safety"],
|
||||
};
|
||||
|
||||
describe("GuardrailCard", () => {
|
||||
it("should render", () => {
|
||||
render(<GuardrailCard card={baseCard} onClick={vi.fn()} />);
|
||||
expect(screen.getByText("Test Guardrail")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("should display the card description", () => {
|
||||
render(<GuardrailCard card={baseCard} onClick={vi.fn()} />);
|
||||
expect(screen.getByText("A guardrail for testing purposes")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("should call onClick when the card is clicked", async () => {
|
||||
const onClick = vi.fn();
|
||||
const user = userEvent.setup();
|
||||
render(<GuardrailCard card={baseCard} onClick={onClick} />);
|
||||
|
||||
await user.click(screen.getByText("Test Guardrail"));
|
||||
|
||||
expect(onClick).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should show eval badge when card has eval data", () => {
|
||||
const cardWithEval: GuardrailCardInfo = {
|
||||
...baseCard,
|
||||
eval: { f1: 95, precision: 92, recall: 98, testCases: 500, latency: "10ms" },
|
||||
};
|
||||
render(<GuardrailCard card={cardWithEval} onClick={vi.fn()} />);
|
||||
expect(screen.getByText(/F1: 95%/)).toBeInTheDocument();
|
||||
expect(screen.getByText(/500 test cases/)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("should not show eval badge when card has no eval data", () => {
|
||||
render(<GuardrailCard card={baseCard} onClick={vi.fn()} />);
|
||||
expect(screen.queryByText(/F1:/)).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("should show fallback initial when logo fails to load", () => {
|
||||
render(<GuardrailCard card={baseCard} onClick={vi.fn()} />);
|
||||
const img = screen.getByRole("presentation");
|
||||
|
||||
act(() => {
|
||||
fireEvent.error(img);
|
||||
});
|
||||
|
||||
expect(screen.getByText("T")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("should show fallback initial when logo src is empty", () => {
|
||||
const cardNoLogo: GuardrailCardInfo = { ...baseCard, logo: "" };
|
||||
render(<GuardrailCard card={cardNoLogo} onClick={vi.fn()} />);
|
||||
expect(screen.getByText("T")).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,71 @@
|
||||
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
||||
import { render, screen, act } from "@testing-library/react";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
import CreatedKeyDisplay from "./CreatedKeyDisplay";
|
||||
|
||||
vi.mock("antd", async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import("antd")>();
|
||||
return {
|
||||
...actual,
|
||||
message: { success: vi.fn() },
|
||||
};
|
||||
});
|
||||
|
||||
import { message } from "antd";
|
||||
|
||||
describe("CreatedKeyDisplay", () => {
|
||||
beforeEach(() => {
|
||||
vi.useFakeTimers({ shouldAdvanceTime: true });
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
it("should render", () => {
|
||||
render(<CreatedKeyDisplay apiKey="sk-test-123" />);
|
||||
expect(screen.getByText("sk-test-123")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("should display the security warning", () => {
|
||||
render(<CreatedKeyDisplay apiKey="sk-test-123" />);
|
||||
expect(screen.getByText(/you will not be able to view it again/i)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("should show the copy button with initial label", () => {
|
||||
render(<CreatedKeyDisplay apiKey="sk-test-123" />);
|
||||
expect(screen.getByRole("button", { name: /copy virtual key/i })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("should change button text to Copied after clicking copy", async () => {
|
||||
const user = userEvent.setup({ advanceTimers: vi.advanceTimersByTime });
|
||||
render(<CreatedKeyDisplay apiKey="sk-test-123" />);
|
||||
|
||||
await user.click(screen.getByRole("button", { name: /copy virtual key/i }));
|
||||
|
||||
expect(screen.getByRole("button", { name: /copied/i })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("should show a success message when the key is copied", async () => {
|
||||
const user = userEvent.setup({ advanceTimers: vi.advanceTimersByTime });
|
||||
render(<CreatedKeyDisplay apiKey="sk-test-123" />);
|
||||
|
||||
await user.click(screen.getByRole("button", { name: /copy virtual key/i }));
|
||||
|
||||
expect(message.success).toHaveBeenCalledWith("Key copied to clipboard");
|
||||
});
|
||||
|
||||
it("should revert button text back after 2 seconds", async () => {
|
||||
const user = userEvent.setup({ advanceTimers: vi.advanceTimersByTime });
|
||||
render(<CreatedKeyDisplay apiKey="sk-test-123" />);
|
||||
|
||||
await user.click(screen.getByRole("button", { name: /copy virtual key/i }));
|
||||
expect(screen.getByRole("button", { name: /copied/i })).toBeInTheDocument();
|
||||
|
||||
act(() => {
|
||||
vi.advanceTimersByTime(2000);
|
||||
});
|
||||
|
||||
expect(screen.getByRole("button", { name: /copy virtual key/i })).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,27 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import { render, screen } from "@testing-library/react";
|
||||
import { ChartLoader } from "./chart_loader";
|
||||
|
||||
describe("ChartLoader", () => {
|
||||
it("should render", () => {
|
||||
render(<ChartLoader />);
|
||||
expect(screen.getByText("Loading chart data...")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("should show loading text by default", () => {
|
||||
render(<ChartLoader />);
|
||||
expect(screen.getByText("Fetching your data")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("should show date-changing text when isDateChanging is true", () => {
|
||||
render(<ChartLoader isDateChanging />);
|
||||
expect(screen.getByText("Processing date selection...")).toBeInTheDocument();
|
||||
expect(screen.getByText("This will only take a moment")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("should not show default loading text when isDateChanging is true", () => {
|
||||
render(<ChartLoader isDateChanging />);
|
||||
expect(screen.queryByText("Loading chart data...")).not.toBeInTheDocument();
|
||||
expect(screen.queryByText("Fetching your data")).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user