From d52d8d10da0e2525c0b13acd125a8a714d29231c Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Mon, 25 May 2026 22:40:15 +0200 Subject: [PATCH] test(control-ui): cover stale overview usage refresh --- ...app-settings.refresh-active-tab.node.test.ts | 17 +++++++++++++++++ ui/src/ui/app-settings.ts | 5 ++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/ui/src/ui/app-settings.refresh-active-tab.node.test.ts b/ui/src/ui/app-settings.refresh-active-tab.node.test.ts index 3c16af25d4e..02adea8fad9 100644 --- a/ui/src/ui/app-settings.refresh-active-tab.node.test.ts +++ b/ui/src/ui/app-settings.refresh-active-tab.node.test.ts @@ -330,6 +330,23 @@ describe("refreshActiveTab", () => { expect(mocks.loadUsageMock).toHaveBeenCalled(); }); + it("skips overview usage refresh if the user leaves while primary loaders run", async () => { + const host = createHost(); + host.tab = "overview"; + const channels = createDeferred(); + mocks.loadChannelsMock.mockReturnValueOnce(channels.promise); + + const refresh = refreshActiveTab(host as never); + await Promise.resolve(); + host.tab = "sessions"; + channels.resolve(); + + await refresh; + + expect(mocks.loadUsageMock).not.toHaveBeenCalled(); + expect(mocks.loadSkillsMock).toHaveBeenCalledOnce(); + }); + it("does not wait for config schema before resolving config tab refresh", async () => { const host = createHost(); host.tab = "config"; diff --git a/ui/src/ui/app-settings.ts b/ui/src/ui/app-settings.ts index c2b730c717e..57db6c3e9d4 100644 --- a/ui/src/ui/app-settings.ts +++ b/ui/src/ui/app-settings.ts @@ -741,9 +741,8 @@ export async function loadOverview(host: SettingsHost, opts?: { refresh?: boolea void Promise.allSettled([ loadDebug(app), loadSkills(app), - // Only fetch usage data if the overview tab is still active. The user may - // have navigated away during the async primary load, in which case firing - // usage.cost is wasteful — especially expensive on 5.22 (pre-beta.2). + // The primary overview loaders can finish after the user has navigated away. + // Avoid starting the expensive usage RPC for stale overview refreshes. isCurrentOverviewRefresh() ? loadUsage(app) : Promise.resolve(), loadOverviewLogs(app), // `refresh: true` bypasses the gateway's 60s auth-status cache so a