Merge pull request #34696 from cat0825/fix/34379-unblock-customer

fix(proxy): allow unblocking customers via /customer/update
This commit is contained in:
Mateo Wang 2026-08-31 13:21:00 -07:00 committed by GitHub
commit 66295e7da7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 45 additions and 5 deletions

View file

@ -626,11 +626,7 @@ async def update_end_user(
# get non default values for key
non_default_values: Final = dict[str, object]()
for k, v in data_json.items():
if v is not None and v not in (
[],
{},
0,
): # models default to [], spend defaults to 0, we should not reset these values
if v is not None and ((isinstance(v, bool) and k in data.fields_set()) or v not in ([], {}, 0)):
non_default_values[k] = v
## Get end user table data ##

View file

@ -83,6 +83,50 @@ def test_update_customer_success(mock_prisma_client, mock_user_api_key_auth):
assert response.json()["alias"] == "Updated Test User"
def test_update_customer_unblock(mock_prisma_client, mock_user_api_key_auth):
mock_end_user = LiteLLM_EndUserTable(user_id="test-user-1", blocked=True)
updated_mock_end_user = LiteLLM_EndUserTable(user_id="test-user-1", blocked=False)
mock_prisma_client.db.litellm_endusertable.find_first = AsyncMock(return_value=mock_end_user)
mock_prisma_client.db.litellm_endusertable.update = AsyncMock(return_value=updated_mock_end_user)
response = client.post(
"/customer/update",
json={"user_id": "test-user-1", "blocked": False},
headers={"Authorization": "Bearer test-key"},
)
assert response.status_code == 200
assert response.json()["blocked"] is False
update_mock = mock_prisma_client.db.litellm_endusertable.update
update_mock.assert_called_once()
assert update_mock.call_args.kwargs["data"]["blocked"] is False
def test_update_customer_keeps_blocked_when_omitted(mock_prisma_client, mock_user_api_key_auth):
"""
Regression test: updating a blocked customer without supplying `blocked`
must NOT reset it to unblocked. `blocked=False` is the model default and
should only be applied when explicitly provided by the caller.
"""
mock_end_user = LiteLLM_EndUserTable(user_id="test-user-1", blocked=True)
updated_mock_end_user = LiteLLM_EndUserTable(user_id="test-user-1", blocked=True)
mock_prisma_client.db.litellm_endusertable.find_first = AsyncMock(return_value=mock_end_user)
mock_prisma_client.db.litellm_endusertable.update = AsyncMock(return_value=updated_mock_end_user)
response = client.post(
"/customer/update",
json={"user_id": "test-user-1", "alias": "Updated Test User"},
headers={"Authorization": "Bearer test-key"},
)
assert response.status_code == 200
update_mock = mock_prisma_client.db.litellm_endusertable.update
update_mock.assert_called_once()
assert "blocked" not in update_mock.call_args.kwargs["data"]
def test_update_customer_not_found(mock_prisma_client, mock_user_api_key_auth):
"""
Test that update_end_user raises a 404 ProxyException when user_id does not exist.