From 884d93ce15a18251002c7f793bbe20efa9fbfc86 Mon Sep 17 00:00:00 2001 From: Tin Date: Tue, 11 Aug 2026 21:38:14 -0700 Subject: [PATCH] test(ui): scope the role-gate assertions to each page's own endpoint The memory, workflows, and guardrails-monitor page tests asserted that a denied role fires no request at all. Their names, and the assertion on the very next line, say the intent is narrower: the page must not fetch its own data. Resolving whether a caller is an org admin goes through /organization/list for every role, since deciding org-admin-for-any-org needs the list, and the route scopes rows per caller. That legitimate request fails a blanket no-fetch assertion, so all three files went red on staging for a reason unrelated to what they test. Drops the blanket assertion and keeps the scoped one. Bypassing the gate in memory/page.tsx still fails five tests, so the narrower assertion continues to catch a genuinely broken gate. --- .../(dashboard)/guardrails-monitor/page.integration.test.tsx | 4 +++- .../src/app/(dashboard)/memory/page.integration.test.tsx | 4 +++- .../src/app/(dashboard)/workflows/page.integration.test.tsx | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/page.integration.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/page.integration.test.tsx index d4c68841299..f9ad62d7f5b 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/page.integration.test.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/page.integration.test.tsx @@ -46,7 +46,9 @@ describe("Guardrails Monitor page access by role", () => { renderAs(userRole); expect(await screen.findByText("Guardrails Monitor is only available to admin users.")).toBeInTheDocument(); - await waitFor(() => expect(fetchMock).not.toHaveBeenCalled()); + // Scoped to this page's own endpoint, not every request. Resolving whether a caller is an org + // admin goes through /organization/list for every role, so a blanket "no fetch at all" would + // fail on a request that has nothing to do with this page's gate. expect(requestedUrls().filter((url) => url.includes("/guardrails/usage"))).toEqual([]); }, ); diff --git a/ui/litellm-dashboard/src/app/(dashboard)/memory/page.integration.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/memory/page.integration.test.tsx index 8d15bb59187..4bd95b51063 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/memory/page.integration.test.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/memory/page.integration.test.tsx @@ -46,7 +46,9 @@ describe("Memory page access by role", () => { renderAs(userRole); expect(await screen.findByText("Memory is only available to admin users.")).toBeInTheDocument(); - await waitFor(() => expect(fetchMock).not.toHaveBeenCalled()); + // Scoped to this page's own endpoint, not every request. Resolving whether a caller is an org + // admin goes through /organization/list for every role, so a blanket "no fetch at all" would + // fail on a request that has nothing to do with this page's gate. expect(requestedUrls().filter((url) => url.includes("/v1/memory"))).toEqual([]); }, ); diff --git a/ui/litellm-dashboard/src/app/(dashboard)/workflows/page.integration.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/workflows/page.integration.test.tsx index 6b332faf704..035261e8220 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/workflows/page.integration.test.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/workflows/page.integration.test.tsx @@ -46,7 +46,9 @@ describe("Workflows page access by role", () => { renderAs(userRole); expect(await screen.findByText("Workflow Runs is only available to admin users.")).toBeInTheDocument(); - await waitFor(() => expect(fetchMock).not.toHaveBeenCalled()); + // Scoped to this page's own endpoint, not every request. Resolving whether a caller is an org + // admin goes through /organization/list for every role, so a blanket "no fetch at all" would + // fail on a request that has nothing to do with this page's gate. expect(requestedUrls().filter((url) => url.includes("/v1/workflows"))).toEqual([]); }, );