mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-06 02:48:13 +00:00
fix(ui): keep an untouched member budget duration distinct from never resets
The member duration dropdown reused its placeholder as "Never resets", so a team with no member budget yet showed "Never resets" while sending nothing and inheriting the team's own reset period. Use the dropdown's never-resets sentinel for an explicit null and label the untouched state as inheriting.
This commit is contained in:
parent
99d4741586
commit
f2f389cc6f
2 changed files with 41 additions and 7 deletions
|
|
@ -4,7 +4,7 @@ import { fireEvent, screen, waitFor, within } from "@testing-library/react";
|
|||
import userEvent from "@testing-library/user-event";
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { chooseSelectOption, renderWithProviders, testQueryClient } from "../../../tests/test-utils";
|
||||
import TeamInfoView from "./TeamInfo";
|
||||
import TeamInfoView, { type TeamData } from "./TeamInfo";
|
||||
|
||||
const authState = vi.hoisted(() => ({ userRole: "Admin" }));
|
||||
|
||||
|
|
@ -1613,10 +1613,18 @@ describe("TeamInfoView - which team member fields reach the update payload depen
|
|||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
const openEditor = async (user: ReturnType<typeof userEvent.setup>) => {
|
||||
const openEditor = async (
|
||||
user: ReturnType<typeof userEvent.setup>,
|
||||
teamMemberBudgetTable: TeamData["team_info"]["team_member_budget_table"] = {
|
||||
max_budget: 42,
|
||||
budget_duration: "30d",
|
||||
tpm_limit: 11,
|
||||
rpm_limit: 22,
|
||||
},
|
||||
) => {
|
||||
vi.mocked(networking.teamInfoCall).mockResolvedValue(
|
||||
createMockTeamData({
|
||||
team_member_budget_table: { max_budget: 42, budget_duration: "30d", tpm_limit: 11, rpm_limit: 22 },
|
||||
team_member_budget_table: teamMemberBudgetTable,
|
||||
default_team_member_models: ["gpt-4"],
|
||||
}),
|
||||
);
|
||||
|
|
@ -1682,6 +1690,31 @@ describe("TeamInfoView - which team member fields reach the update payload depen
|
|||
expect(JSON.stringify(payload)).toContain('"team_member_budget_duration":null');
|
||||
});
|
||||
|
||||
it("shows Never resets for a stored member budget whose duration is null", async () => {
|
||||
const user = userEvent.setup({ delay: null });
|
||||
await openEditor(user, { max_budget: 42, budget_duration: null, tpm_limit: null, rpm_limit: null });
|
||||
|
||||
await user.click(screen.getByText("Team Member Settings"));
|
||||
|
||||
expect(await screen.findByLabelText("Default Budget Duration")).toHaveTextContent("Never resets");
|
||||
});
|
||||
|
||||
it("omits team_member_budget_duration when the dropdown is left untouched on a team with no member budget", async () => {
|
||||
const user = userEvent.setup({ delay: null });
|
||||
await openEditor(user, null);
|
||||
|
||||
await user.click(screen.getByText("Team Member Settings"));
|
||||
const durationSelect = await screen.findByLabelText("Default Budget Duration");
|
||||
expect(durationSelect).toHaveTextContent("Inherit team reset period");
|
||||
expect(durationSelect).not.toHaveTextContent("Never resets");
|
||||
await user.type(screen.getByLabelText("Default Budget (USD)"), "100");
|
||||
|
||||
const payload = await save(user);
|
||||
|
||||
expect(payload.team_member_budget).toBe(100);
|
||||
expect(JSON.parse(JSON.stringify(payload))).not.toHaveProperty("team_member_budget_duration");
|
||||
});
|
||||
|
||||
it("omits object_permission.search_tools while Search Tool Settings is closed", async () => {
|
||||
const user = userEvent.setup({ delay: null });
|
||||
await openEditor(user);
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ import { z } from "zod/v4";
|
|||
import GuardrailsSelect from "./GuardrailsSelect";
|
||||
import { copyToClipboard as utilCopyToClipboard } from "../../utils/dataUtils";
|
||||
import AccessGroupSelector from "../common_components/AccessGroupSelector";
|
||||
import BudgetDurationDropdown from "../common_components/budget_duration_dropdown";
|
||||
import BudgetDurationDropdown, { NEVER_RESETS_BUDGET_DURATION } from "../common_components/budget_duration_dropdown";
|
||||
import {
|
||||
computeTeamModelBadges,
|
||||
normalizeTeamModelSelection,
|
||||
|
|
@ -1258,9 +1258,10 @@ const TeamInfoView: React.FC<TeamInfoProps> = ({
|
|||
{({ id, value, onChange }) => (
|
||||
<BudgetDurationDropdown
|
||||
id={id}
|
||||
placeholder="Never resets"
|
||||
value={value}
|
||||
onChange={(next) => onChange(next ?? null)}
|
||||
showNeverResets
|
||||
placeholder="Inherit team reset period"
|
||||
value={value === null ? NEVER_RESETS_BUDGET_DURATION : value}
|
||||
onChange={(next) => onChange(next === NEVER_RESETS_BUDGET_DURATION ? null : next)}
|
||||
/>
|
||||
)}
|
||||
</FormField>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue