diff --git a/ui/litellm-dashboard/src/components/CreateUserButton.test.tsx b/ui/litellm-dashboard/src/components/CreateUserButton.test.tsx index 03d982ca7c..d3e2e45290 100644 --- a/ui/litellm-dashboard/src/components/CreateUserButton.test.tsx +++ b/ui/litellm-dashboard/src/components/CreateUserButton.test.tsx @@ -354,4 +354,126 @@ describe("CreateUserButton", () => { expect(mockOrganizationMemberAddCall).not.toHaveBeenCalled(); }); }); + + describe("send invitation email toggle", () => { + it("should send send_invite_email true by default in embedded mode", async () => { + const user = userEvent.setup(); + mockUserCreateCall.mockResolvedValue({ data: { user_id: "default-on-user" } }); + + renderWithProviders( + , + ); + + await user.type(screen.getByLabelText(/user email/i), "default@example.com"); + await user.click(screen.getByRole("combobox", { name: /user role/i })); + await user.click(screen.getByText("User")); + await user.click(screen.getByRole("button", { name: /create user/i })); + + await waitFor(() => { + expect(mockUserCreateCall).toHaveBeenCalledWith("token", null, expect.objectContaining({ + send_invite_email: true, + })); + }); + }); + + it("should send send_invite_email false when the checkbox is unchecked in embedded mode", async () => { + const user = userEvent.setup(); + mockUserCreateCall.mockResolvedValue({ data: { user_id: "unchecked-user" } }); + + renderWithProviders( + , + ); + + await user.type(screen.getByLabelText(/user email/i), "off@example.com"); + await user.click(screen.getByRole("combobox", { name: /user role/i })); + await user.click(screen.getByText("User")); + await user.click(screen.getByRole("checkbox", { name: /send invitation email/i })); + await user.click(screen.getByRole("button", { name: /create user/i })); + + await waitFor(() => { + expect(mockUserCreateCall).toHaveBeenCalledWith("token", null, expect.objectContaining({ + send_invite_email: false, + })); + }); + }); + + it("should send send_invite_email true by default in standalone mode", async () => { + const user = userEvent.setup(); + mockUserCreateCall.mockResolvedValue({ data: { user_id: "standalone-default-user" } }); + mockInvitationCreateCall.mockResolvedValue({ + id: "inv-default", + user_id: "standalone-default-user", + has_user_setup_sso: false, + } as any); + + renderWithProviders( + , + ); + + await waitFor(() => { + expect(screen.getByRole("button", { name: /\+ invite user/i })).toBeInTheDocument(); + }); + await user.click(screen.getByRole("button", { name: /\+ invite user/i })); + + const dialog = screen.getByRole("dialog", { name: /invite user/i }); + await user.type(within(dialog).getByLabelText(/user email/i), "standalone-default@example.com"); + await user.click(within(dialog).getByRole("combobox", { name: /global proxy role/i })); + await user.click(screen.getByText("User")); + await user.click(within(dialog).getByRole("button", { name: /invite user/i })); + + await waitFor(() => { + expect(mockUserCreateCall).toHaveBeenCalledWith("token", null, expect.objectContaining({ + send_invite_email: true, + })); + }); + }); + + it("should send send_invite_email false when the checkbox is unchecked in standalone mode", async () => { + const user = userEvent.setup(); + mockUserCreateCall.mockResolvedValue({ data: { user_id: "standalone-off-user" } }); + mockInvitationCreateCall.mockResolvedValue({ + id: "inv-off", + user_id: "standalone-off-user", + has_user_setup_sso: false, + } as any); + + renderWithProviders( + , + ); + + await waitFor(() => { + expect(screen.getByRole("button", { name: /\+ invite user/i })).toBeInTheDocument(); + }); + await user.click(screen.getByRole("button", { name: /\+ invite user/i })); + + const dialog = screen.getByRole("dialog", { name: /invite user/i }); + await user.type(within(dialog).getByLabelText(/user email/i), "standalone-off@example.com"); + await user.click(within(dialog).getByRole("combobox", { name: /global proxy role/i })); + await user.click(screen.getByText("User")); + await user.click(within(dialog).getByRole("checkbox", { name: /send invitation email/i })); + await user.click(within(dialog).getByRole("button", { name: /invite user/i })); + + await waitFor(() => { + expect(mockUserCreateCall).toHaveBeenCalledWith("token", null, expect.objectContaining({ + send_invite_email: false, + })); + }); + }); + + it("should keep the checkbox checked by default when the modal is opened in standalone mode", async () => { + const user = userEvent.setup(); + + renderWithProviders( + , + ); + + await waitFor(() => { + expect(screen.getByRole("button", { name: /\+ invite user/i })).toBeInTheDocument(); + }); + await user.click(screen.getByRole("button", { name: /\+ invite user/i })); + + const dialog = screen.getByRole("dialog", { name: /invite user/i }); + expect(within(dialog).getByRole("checkbox", { name: /send invitation email/i })).toBeChecked(); + }); + }); }); diff --git a/ui/litellm-dashboard/src/components/CreateUserButton.tsx b/ui/litellm-dashboard/src/components/CreateUserButton.tsx index 7d2fc10150..5a3c035bd6 100644 --- a/ui/litellm-dashboard/src/components/CreateUserButton.tsx +++ b/ui/litellm-dashboard/src/components/CreateUserButton.tsx @@ -225,15 +225,21 @@ export const CreateUserButton: React.FC = ({ - - Send invitation email - - -
+ + Send invitation email +
@@ -370,15 +376,21 @@ export const CreateUserButton: React.FC = ({ - - Send invitation email - - -
+ + Send invitation email +