test(auth): model the membership row read in the fakes the loader now reaches

This commit is contained in:
mateo-berri 2026-09-19 16:32:22 -07:00
parent 484524b70b
commit b3b280d463
4 changed files with 12 additions and 8 deletions

View file

@ -201,6 +201,14 @@ async def test_returned_user_api_key_auth(user_role, expected_role):
assert new_obj.user_role == expected_role
class _NoMembershipRowPrisma:
class db:
class litellm_teammembership:
@staticmethod
async def find_unique(where: dict[str, dict[str, str]], include: dict[str, bool]) -> None:
return None
@pytest.mark.parametrize("key_ownership", ["user_key", "team_key"])
@pytest.mark.asyncio
async def test_aaauser_personal_budgets(key_ownership):
@ -253,7 +261,7 @@ async def test_aaauser_personal_budgets(key_ownership):
setattr(litellm.proxy.proxy_server, "user_api_key_cache", user_api_key_cache)
setattr(litellm.proxy.proxy_server, "master_key", "sk-1234")
setattr(litellm.proxy.proxy_server, "prisma_client", "hello-world")
setattr(litellm.proxy.proxy_server, "prisma_client", _NoMembershipRowPrisma())
request = Request(scope={"type": "http"})
request._url = URL(url="/chat/completions")

View file

@ -11515,7 +11515,9 @@ def jwt_oauth_identity(monkeypatch: pytest.MonkeyPatch) -> tuple["JWTHandler", "
monkeypatch.setattr(proxy_server, "general_settings", {"enable_jwt_auth": True})
monkeypatch.setattr(proxy_server, "premium_user", True)
monkeypatch.setattr(proxy_server, "user_api_key_cache", cache)
monkeypatch.setattr(proxy_server, "prisma_client", MagicMock())
prisma: Final = MagicMock()
prisma.db.litellm_teammembership.find_unique = AsyncMock(return_value=None)
monkeypatch.setattr(proxy_server, "prisma_client", prisma)
return handler, signing_key

View file

@ -7257,9 +7257,6 @@ def _restricted_member_check_deps() -> dict[str, object]:
@pytest.mark.asyncio
async def test_check_team_member_model_access_fails_closed_when_the_membership_read_hits_a_db_outage():
"""Regression: with the member's row uncached and the database unreachable, the loader used to swallow the
transport error and return None, which every check reads as "no per-member restriction", so a member
limited to other models got a 200. The outage must surface as the 503 the rest of auth answers with."""
from litellm.proxy.auth.auth_checks import _check_team_member_model_access
from litellm.proxy.auth.auth_exception_handler import _as_proxy_exception

View file

@ -183,9 +183,6 @@ class _UnreachableMembershipPrisma:
async def test_resolve_marks_a_membership_read_that_hits_a_db_outage_as_degraded():
"""Regression: the real membership loader swallowed a database transport error into None, so this outcome
was ResolvedGrants with no membership, never LookupDegraded, and a member's own model or budget limits
silently dropped for the request."""
loaders = _Loaders(user=_user(), team=_team())
resolver = GrantResolver(
_UnreachableMembershipPrisma(),