diff --git a/ui/litellm-dashboard/src/components/bulk_create_users_button.test.tsx b/ui/litellm-dashboard/src/components/bulk_create_users_button.test.tsx index 7397eaa6b24..dd3439c0bba 100644 --- a/ui/litellm-dashboard/src/components/bulk_create_users_button.test.tsx +++ b/ui/litellm-dashboard/src/components/bulk_create_users_button.test.tsx @@ -1,4 +1,4 @@ -import { render } from "@testing-library/react"; +import { fireEvent, render } from "@testing-library/react"; import { describe, it, expect, vi } from "vitest"; import BulkCreateUsersButton from "./bulk_create_users_button"; @@ -25,4 +25,50 @@ describe("BulkCreateUsersButton", () => { const { getByText } = render(); expect(getByText("+ Bulk Invite Users")).toBeInTheDocument(); }); + + it("downloads the CSV template when clicked", async () => { + const originalCreateObjectURL = window.URL.createObjectURL; + const originalRevokeObjectURL = window.URL.revokeObjectURL; + const createObjectURLSpy = vi.fn(() => "blob:test"); + const revokeObjectURLSpy = vi.fn(); + const appendChildSpy = vi.spyOn(document.body, "appendChild"); + const removeChildSpy = vi.spyOn(document.body, "removeChild"); + const clickSpy = vi.fn(); + const originalCreateElement = document.createElement.bind(document); + let createdAnchor: HTMLAnchorElement | null = null; + + window.URL.createObjectURL = createObjectURLSpy; + window.URL.revokeObjectURL = revokeObjectURLSpy; + + const createElementSpy = vi.spyOn(document, "createElement").mockImplementation((tagName: string) => { + if (tagName === "a") { + const anchor = originalCreateElement("a"); + anchor.click = clickSpy; + createdAnchor = anchor; + return anchor; + } + + return originalCreateElement(tagName); + }); + + const { getByText, findByText } = render( + + ); + + fireEvent.click(getByText("+ Bulk Invite Users")); + fireEvent.click(await findByText("Download CSV Template")); + + expect(createObjectURLSpy).toHaveBeenCalledOnce(); + expect(clickSpy).toHaveBeenCalledOnce(); + expect(createdAnchor).not.toBeNull(); + expect(appendChildSpy).toHaveBeenCalledWith(createdAnchor); + expect(removeChildSpy).toHaveBeenCalledWith(createdAnchor); + expect(revokeObjectURLSpy).toHaveBeenCalledWith("blob:test"); + + appendChildSpy.mockRestore(); + removeChildSpy.mockRestore(); + createElementSpy.mockRestore(); + window.URL.createObjectURL = originalCreateObjectURL; + window.URL.revokeObjectURL = originalRevokeObjectURL; + }); }); diff --git a/ui/litellm-dashboard/src/components/bulk_create_users_button.tsx b/ui/litellm-dashboard/src/components/bulk_create_users_button.tsx index 4d0eb254d0d..28016266269 100644 --- a/ui/litellm-dashboard/src/components/bulk_create_users_button.tsx +++ b/ui/litellm-dashboard/src/components/bulk_create_users_button.tsx @@ -629,7 +629,13 @@ const BulkCreateUsersButton: React.FC = ({ -