mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-09 03:18:44 +00:00
[Test] Add tests for organization dropdown in key create/edit
- OrganizationDropdown: renders options, calls onChange on selection, applies disabled state, handles empty list - CreateKey: org dropdown renders, disabled for non-admin users, enabled for admins, form state updates on org selection - KeyEditView: org dropdown renders, disabled for non-admin, enabled for admin, initializes from keyData.organization_id Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
c637c93a6a
commit
bce37e28c3
3 changed files with 284 additions and 1 deletions
|
|
@ -0,0 +1,69 @@
|
|||
import { render, screen } from "@testing-library/react";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import OrganizationDropdown from "./OrganizationDropdown";
|
||||
|
||||
const MOCK_ORGS = [
|
||||
{
|
||||
organization_id: "org-1",
|
||||
organization_alias: "Engineering",
|
||||
budget_id: "",
|
||||
metadata: {},
|
||||
models: [],
|
||||
spend: 0,
|
||||
model_spend: {},
|
||||
created_at: "",
|
||||
created_by: "",
|
||||
updated_at: "",
|
||||
},
|
||||
{
|
||||
organization_id: "org-2",
|
||||
organization_alias: "Sales",
|
||||
budget_id: "",
|
||||
metadata: {},
|
||||
models: [],
|
||||
spend: 0,
|
||||
model_spend: {},
|
||||
created_at: "",
|
||||
created_by: "",
|
||||
updated_at: "",
|
||||
},
|
||||
];
|
||||
|
||||
describe("OrganizationDropdown", () => {
|
||||
it("should render", () => {
|
||||
render(<OrganizationDropdown organizations={MOCK_ORGS} />);
|
||||
expect(screen.getByRole("combobox")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("should display organization options when opened", async () => {
|
||||
const user = userEvent.setup();
|
||||
render(<OrganizationDropdown organizations={MOCK_ORGS} />);
|
||||
|
||||
await user.click(screen.getByRole("combobox"));
|
||||
|
||||
expect(await screen.findByText("Engineering")).toBeInTheDocument();
|
||||
expect(screen.getByText("Sales")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("should call onChange with the org id when an organization is selected", async () => {
|
||||
const onChange = vi.fn();
|
||||
const user = userEvent.setup();
|
||||
render(<OrganizationDropdown organizations={MOCK_ORGS} onChange={onChange} />);
|
||||
|
||||
await user.click(screen.getByRole("combobox"));
|
||||
await user.click(await screen.findByText("Engineering"));
|
||||
|
||||
expect(onChange).toHaveBeenCalledWith("org-1", expect.anything());
|
||||
});
|
||||
|
||||
it("should add ant-select-disabled class when disabled prop is true", () => {
|
||||
const { container } = render(<OrganizationDropdown organizations={MOCK_ORGS} disabled={true} />);
|
||||
expect(container.querySelector(".ant-select-disabled")).toBeTruthy();
|
||||
});
|
||||
|
||||
it("should render with empty organizations list", () => {
|
||||
render(<OrganizationDropdown organizations={[]} />);
|
||||
expect(screen.getByRole("combobox")).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
|
@ -213,7 +213,22 @@ vi.mock("../common_components/PassThroughRoutesSelector", () => ({ default: () =
|
|||
vi.mock("../common_components/PremiumLoggingSettings", () => ({ default: () => null }));
|
||||
vi.mock("../common_components/RateLimitTypeFormItem", () => ({ default: () => null }));
|
||||
vi.mock("../common_components/RouterSettingsAccordion", () => ({ default: () => null }));
|
||||
vi.mock("../common_components/team_dropdown", () => ({ default: () => null }));
|
||||
vi.mock("../common_components/team_dropdown", () => ({
|
||||
default: ({ teams, onChange, disabled }: { teams?: any[]; onChange?: (v: string) => void; disabled?: boolean }) => (
|
||||
<select
|
||||
data-testid="team-dropdown"
|
||||
disabled={disabled}
|
||||
onChange={(e) => onChange?.(e.target.value)}
|
||||
>
|
||||
<option value="">Select team</option>
|
||||
{teams?.map((t: any) => (
|
||||
<option key={t.team_id} value={t.team_id}>
|
||||
{t.team_alias}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
),
|
||||
}));
|
||||
vi.mock("../CreateUserButton", () => ({ CreateUserButton: () => null }));
|
||||
vi.mock("../mcp_server_management/MCPServerSelector", () => ({ default: () => null }));
|
||||
vi.mock("../mcp_server_management/MCPToolPermissions", () => ({ default: () => null }));
|
||||
|
|
@ -227,6 +242,31 @@ vi.mock("@/app/(dashboard)/hooks/projects/useProjects", () => ({
|
|||
useProjects: vi.fn().mockReturnValue({ data: [], isLoading: false }),
|
||||
}));
|
||||
|
||||
vi.mock("@/app/(dashboard)/hooks/organizations/useOrganizations", () => ({
|
||||
useOrganizations: vi.fn().mockReturnValue({
|
||||
data: [
|
||||
{ organization_id: "org-1", organization_alias: "Engineering" },
|
||||
{ organization_id: "org-2", organization_alias: "Sales" },
|
||||
],
|
||||
isLoading: false,
|
||||
}),
|
||||
}));
|
||||
|
||||
vi.mock("../common_components/OrganizationDropdown", () => ({
|
||||
default: ({ value, onChange, disabled }: { value?: string; onChange?: (v: string) => void; disabled?: boolean }) => (
|
||||
<select
|
||||
data-testid="org-dropdown"
|
||||
disabled={disabled}
|
||||
value={value || ""}
|
||||
onChange={(e) => onChange?.(e.target.value)}
|
||||
>
|
||||
<option value="">Select org</option>
|
||||
<option value="org-1">Engineering</option>
|
||||
<option value="org-2">Sales</option>
|
||||
</select>
|
||||
),
|
||||
}));
|
||||
|
||||
vi.mock("../common_components/ProjectDropdown", () => ({
|
||||
default: ({ value, onChange }: { value?: string; onChange?: (v: string) => void }) => (
|
||||
<input
|
||||
|
|
@ -408,4 +448,81 @@ describe("CreateKey", () => {
|
|||
expect(setFieldsValueMock).toHaveBeenCalledWith({ key_type: "management" });
|
||||
});
|
||||
});
|
||||
|
||||
describe("organization dropdown", () => {
|
||||
it("should render the organization dropdown when modal is open", async () => {
|
||||
renderWithProviders(<CreateKey {...defaultProps} />);
|
||||
|
||||
act(() => {
|
||||
fireEvent.click(screen.getByRole("button", { name: /create new key/i }));
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId("org-dropdown")).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
it("should disable the organization dropdown for non-admin users", async () => {
|
||||
authorizedState = { ...defaultAuthorizedState, userRole: "Internal User" };
|
||||
|
||||
renderWithProviders(<CreateKey {...defaultProps} />);
|
||||
|
||||
act(() => {
|
||||
fireEvent.click(screen.getByRole("button", { name: /create new key/i }));
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId("org-dropdown")).toBeDisabled();
|
||||
});
|
||||
});
|
||||
|
||||
it("should enable the organization dropdown for admin users", async () => {
|
||||
authorizedState = { ...defaultAuthorizedState, userRole: "Admin" };
|
||||
|
||||
renderWithProviders(<CreateKey {...defaultProps} />);
|
||||
|
||||
act(() => {
|
||||
fireEvent.click(screen.getByRole("button", { name: /create new key/i }));
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId("org-dropdown")).not.toBeDisabled();
|
||||
});
|
||||
});
|
||||
|
||||
it("should render team dropdown alongside organization dropdown", async () => {
|
||||
const teamsWithOrg = [
|
||||
{ team_id: "team-1", team_alias: "Team Alpha", organization_id: "org-1", models: [] },
|
||||
];
|
||||
|
||||
renderWithProviders(<CreateKey {...defaultProps} teams={teamsWithOrg as any} />);
|
||||
|
||||
act(() => {
|
||||
fireEvent.click(screen.getByRole("button", { name: /create new key/i }));
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId("org-dropdown")).toBeInTheDocument();
|
||||
expect(screen.getByTestId("team-dropdown")).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
it("should set organization_id in form state when org is selected", async () => {
|
||||
renderWithProviders(<CreateKey {...defaultProps} />);
|
||||
|
||||
act(() => {
|
||||
fireEvent.click(screen.getByRole("button", { name: /create new key/i }));
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId("org-dropdown")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
act(() => {
|
||||
fireEvent.change(screen.getByTestId("org-dropdown"), { target: { value: "org-1" } });
|
||||
});
|
||||
|
||||
expect(formStateRef.current["organization_id"]).toBe("org-1");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -53,6 +53,16 @@ vi.mock("../organisms/create_key_button", () => ({
|
|||
fetchTeamModels: vi.fn().mockResolvedValue(["team-model-1", "team-model-2"]),
|
||||
}));
|
||||
|
||||
vi.mock("@/app/(dashboard)/hooks/organizations/useOrganizations", () => ({
|
||||
useOrganizations: vi.fn().mockReturnValue({
|
||||
data: [
|
||||
{ organization_id: "org-1", organization_alias: "Engineering" },
|
||||
{ organization_id: "org-2", organization_alias: "Sales" },
|
||||
],
|
||||
isLoading: false,
|
||||
}),
|
||||
}));
|
||||
|
||||
vi.mock("@/app/(dashboard)/hooks/accessGroups/useAccessGroups", () => ({
|
||||
useAccessGroups: vi.fn().mockReturnValue({
|
||||
data: [
|
||||
|
|
@ -576,4 +586,91 @@ describe("KeyEditView", () => {
|
|||
resolveSubmit();
|
||||
}
|
||||
});
|
||||
|
||||
describe("organization dropdown", () => {
|
||||
it("should render the organization dropdown", async () => {
|
||||
renderWithProviders(
|
||||
<KeyEditView
|
||||
keyData={MOCK_KEY_DATA}
|
||||
onCancel={() => {}}
|
||||
onSubmit={async () => {}}
|
||||
accessToken=""
|
||||
userID=""
|
||||
userRole="Admin"
|
||||
premiumUser={false}
|
||||
/>,
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText("Organization")).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
it("should disable the organization dropdown for non-admin users", async () => {
|
||||
const { container } = renderWithProviders(
|
||||
<KeyEditView
|
||||
keyData={MOCK_KEY_DATA}
|
||||
onCancel={() => {}}
|
||||
onSubmit={async () => {}}
|
||||
accessToken=""
|
||||
userID=""
|
||||
userRole="Internal User"
|
||||
premiumUser={false}
|
||||
/>,
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText("Organization")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
const orgFormItem = screen.getByText("Organization").closest(".ant-form-item");
|
||||
const disabledSelect = orgFormItem?.querySelector(".ant-select-disabled");
|
||||
expect(disabledSelect).toBeTruthy();
|
||||
});
|
||||
|
||||
it("should not disable the organization dropdown for admin users", async () => {
|
||||
const { container } = renderWithProviders(
|
||||
<KeyEditView
|
||||
keyData={MOCK_KEY_DATA}
|
||||
onCancel={() => {}}
|
||||
onSubmit={async () => {}}
|
||||
accessToken=""
|
||||
userID=""
|
||||
userRole="Admin"
|
||||
premiumUser={false}
|
||||
/>,
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText("Organization")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
const orgFormItem = screen.getByText("Organization").closest(".ant-form-item");
|
||||
const disabledSelect = orgFormItem?.querySelector(".ant-select-disabled");
|
||||
expect(disabledSelect).toBeFalsy();
|
||||
});
|
||||
|
||||
it("should initialize organization from keyData", async () => {
|
||||
const keyWithOrg = {
|
||||
...MOCK_KEY_DATA,
|
||||
organization_id: "org-1",
|
||||
};
|
||||
|
||||
renderWithProviders(
|
||||
<KeyEditView
|
||||
keyData={keyWithOrg}
|
||||
onCancel={() => {}}
|
||||
onSubmit={async () => {}}
|
||||
accessToken=""
|
||||
userID=""
|
||||
userRole="Admin"
|
||||
premiumUser={false}
|
||||
/>,
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText("Engineering")).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue