diff --git a/ui/litellm-dashboard/src/components/shared/copyable_badge.test.tsx b/ui/litellm-dashboard/src/components/shared/copyable_badge.test.tsx index f4c1daa646c..908d6a88471 100644 --- a/ui/litellm-dashboard/src/components/shared/copyable_badge.test.tsx +++ b/ui/litellm-dashboard/src/components/shared/copyable_badge.test.tsx @@ -1,6 +1,8 @@ import { fireEvent, render, screen, waitFor } from "@testing-library/react"; import { beforeEach, describe, expect, it, vi } from "vitest"; +import { TooltipProvider } from "@/components/ui/tooltip"; + import { CopyableBadge } from "./copyable_badge"; const writeText = vi.fn().mockResolvedValue(undefined); @@ -13,29 +15,45 @@ beforeEach(() => { }); }); +const renderBadge = (value: string, maxWidthClassName?: string) => + render( + + + , + ); + +const openTooltip = (value: string) => { + const trigger = screen.getByText(value).parentElement!; + fireEvent.pointerEnter(trigger, { pointerType: "mouse" }); + fireEvent.mouseEnter(trigger); +}; + describe("CopyableBadge", () => { - it("renders the value and truncates it", () => { - render(); + it("renders the value truncated in the badge", () => { + renderBadge("app-aigateway-inference-producttech-product-default"); const label = screen.getByText("app-aigateway-inference-producttech-product-default"); expect(label.className).toContain("truncate"); expect(label.className).toContain("max-w-[220px]"); }); - it("copies the full value when the copy button is clicked", async () => { - render(); + it("reveals the full value and copies it from the hover tooltip", async () => { + renderBadge("team-alias-long-name"); - fireEvent.click(screen.getByRole("button", { name: "Copy team-alias-long-name" })); + openTooltip("team-alias-long-name"); + + const copyButton = await screen.findByRole("button", { name: "Copy team-alias-long-name" }); + fireEvent.click(copyButton); await waitFor(() => expect(writeText).toHaveBeenCalledWith("team-alias-long-name")); }); - it("exposes a copy affordance via accessible label", () => { - render(); - expect(screen.getByRole("button", { name: "Copy my-team" })).toBeInTheDocument(); + it("does not expose the copy affordance until hovered", () => { + renderBadge("my-team"); + expect(screen.queryByRole("button", { name: "Copy my-team" })).not.toBeInTheDocument(); }); it("honors a custom max width", () => { - render(); + renderBadge("short", "max-w-[120px]"); expect(screen.getByText("short").className).toContain("max-w-[120px]"); }); }); diff --git a/ui/litellm-dashboard/src/components/shared/copyable_badge.tsx b/ui/litellm-dashboard/src/components/shared/copyable_badge.tsx index 004325b2c79..b38d37d8b35 100644 --- a/ui/litellm-dashboard/src/components/shared/copyable_badge.tsx +++ b/ui/litellm-dashboard/src/components/shared/copyable_badge.tsx @@ -20,14 +20,23 @@ export function CopyableBadge({ dataTestId, }: CopyableBadgeProps) { return ( - - - - {value} - - {value} - - - + + + {value} + + } + /> + + {value} + + + ); }