mirror of
https://github.com/tiennm99/litellm.git
synced 2026-08-11 00:25:15 +00:00
fix(ui): prefer form values over API echo in regenerate update payload
The regenerate endpoint returns a GenerateKeyResponse that inherits max_budget/tpm_limit/rpm_limit from KeyRequestBase, so the API echoes the existing values back. The previous updatedKeyData layout spread ...response *after* the explicit formValues assignments, which meant the user's just-submitted edits were silently overwritten by the API echo before being propagated to the parent via onKeyUpdate. Reorder so the response spread comes first and the formValues-derived fields override it, and add a regression test that mocks a response with stale limits to lock the behavior in. Also drop the two leftover debug console.log statements.
This commit is contained in:
@@ -219,6 +219,34 @@ describe("RegenerateKeyModal", () => {
|
||||
expect(updateCall.key_name).toBe("sk-new-regenerated-key");
|
||||
});
|
||||
|
||||
it("should pass form values to onKeyUpdate even when the API echoes back different limits", async () => {
|
||||
// Regression: when the regenerate endpoint returns GenerateKeyResponse, it echoes
|
||||
// back the existing max_budget / tpm_limit / rpm_limit. The modal must prefer the
|
||||
// values the user just submitted, not whatever the server echoes.
|
||||
const user = userEvent.setup();
|
||||
mockRegenerateKeyCall.mockResolvedValue({
|
||||
key: "sk-new-regenerated-key",
|
||||
token: "new-token-hash",
|
||||
// stale values echoed from the server
|
||||
max_budget: 9999,
|
||||
tpm_limit: 9999,
|
||||
rpm_limit: 9999,
|
||||
});
|
||||
|
||||
renderWithProviders(<RegenerateKeyModal {...defaultProps} />);
|
||||
await user.click(screen.getByRole("button", { name: /Regenerate/ }));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockOnKeyUpdate).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
const updateCall = mockOnKeyUpdate.mock.calls[0][0];
|
||||
// The form's pre-filled values (from makeToken) must win over the API echo.
|
||||
expect(updateCall.max_budget).toBe(100);
|
||||
expect(updateCall.tpm_limit).toBe(5000);
|
||||
expect(updateCall.rpm_limit).toBe(500);
|
||||
});
|
||||
|
||||
it("should display key alias in success view", async () => {
|
||||
const user = userEvent.setup();
|
||||
mockRegenerateKeyCall.mockResolvedValue({
|
||||
|
||||
@@ -111,23 +111,20 @@ export function RegenerateKeyModal({ selectedToken, visible, onClose, onKeyUpdat
|
||||
setRegeneratedKey(response.key);
|
||||
NotificationManager.success("Virtual Key regenerated successfully");
|
||||
|
||||
console.log("Full regenerate response:", response); // Debug log to see what's returned
|
||||
|
||||
// Create updated key data with ALL new values from the response
|
||||
// Build the update payload. Spread the API response first so any new
|
||||
// fields it returns (new token, timestamps, etc.) are captured, then
|
||||
// override with the explicit form values — the user's just-submitted
|
||||
// edits must win over whatever the API echoes back.
|
||||
const updatedKeyData: Partial<KeyResponse> = {
|
||||
// Use the new token/key ID from the response (this is what was missing!)
|
||||
token: response.token || response.key_id || selectedToken.token, // Try different possible field names
|
||||
key_name: response.key, // This is the new secret key string
|
||||
...response,
|
||||
token: response.token || response.key_id || selectedToken.token,
|
||||
key_name: response.key,
|
||||
max_budget: formValues.max_budget,
|
||||
tpm_limit: formValues.tpm_limit,
|
||||
rpm_limit: formValues.rpm_limit,
|
||||
expires: formValues.duration ? calculateNewExpiryTime(formValues.duration) : selectedToken.expires,
|
||||
// Include any other fields that might be returned by the API
|
||||
...response, // Spread the entire response to capture all updated fields
|
||||
};
|
||||
|
||||
console.log("Updated key data with new token:", updatedKeyData); // Debug log
|
||||
|
||||
// Update the parent component with new key data
|
||||
if (onKeyUpdate) {
|
||||
onKeyUpdate(updatedKeyData);
|
||||
|
||||
Reference in New Issue
Block a user