From 03c730c48f2125cdec8a59e20fb61a1c3abf384a Mon Sep 17 00:00:00 2001 From: Shakker Date: Wed, 3 Jun 2026 23:36:45 +0100 Subject: [PATCH] test: cover awaited chat session switching --- ui/src/ui/app-render.helpers.node.test.ts | 75 +++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/ui/src/ui/app-render.helpers.node.test.ts b/ui/src/ui/app-render.helpers.node.test.ts index 06bc6908e742..57e500b13485 100644 --- a/ui/src/ui/app-render.helpers.node.test.ts +++ b/ui/src/ui/app-render.helpers.node.test.ts @@ -78,6 +78,7 @@ import { resolveSessionOptionGroups, resolveSessionDisplayName, switchChatSession, + switchChatSessionAndWait, } from "./app-render.helpers.ts"; import type { AppViewState } from "./app-view-state.ts"; import type { SessionsListResult } from "./types.ts"; @@ -964,6 +965,80 @@ describe("createChatSession", () => { }); describe("switchChatSession", () => { + it("waits for the initial history and message subscription when requested", async () => { + let resolveHistory!: () => void; + let resolveSubscription!: () => void; + const historyLoaded = new Promise((resolve) => { + resolveHistory = resolve; + }); + const subscriptionSynced = new Promise((resolve) => { + resolveSubscription = resolve; + }); + const settings = createSettings(); + const state = { + sessionKey: "main", + chatMessage: "", + chatAttachments: [], + chatMessages: [], + chatToolMessages: [], + chatStreamSegments: [], + chatThinkingLevel: null, + chatStream: null, + chatSideResult: null, + lastError: null, + compactionStatus: null, + fallbackStatus: null, + chatAvatarUrl: null, + chatQueue: [], + chatQueueBySession: {}, + chatRunId: null, + sessionsShowArchived: false, + chatSideResultTerminalRuns: new Set(), + chatStreamStartedAt: null, + sessionsResult: { + ts: 0, + path: "", + count: 2, + defaults: { modelProvider: "openai", model: "gpt-5", contextTokens: null }, + sessions: [row({ key: "main" }), row({ key: "agent:main:review" })], + }, + settings, + announceSessionSwitch: vi.fn(), + applySettings(next: typeof settings) { + state.settings = next; + }, + loadAssistantIdentity: vi.fn(), + resetToolStream: vi.fn(), + resetChatScroll: vi.fn(), + resetChatInputHistoryNavigation: vi.fn(), + } as unknown as AppViewState; + + refreshChatAvatarMock.mockResolvedValue(undefined); + refreshSlashCommandsMock.mockResolvedValue(undefined); + loadChatHistoryMock.mockReturnValue(historyLoaded); + syncSelectedSessionMessageSubscriptionMock.mockReturnValue(subscriptionSynced); + loadSessionsMock.mockResolvedValue(undefined); + + const switched = switchChatSessionAndWait(state, "agent:main:review"); + let settled = false; + void switched.then(() => { + settled = true; + }); + + await Promise.resolve(); + expect(settled).toBe(false); + + resolveHistory(); + await Promise.resolve(); + expect(settled).toBe(false); + + resolveSubscription(); + await switched; + + expect(settled).toBe(true); + expect(state.sessionKey).toBe("agent:main:review"); + }); + it("refreshes the chat avatar after clearing session-scoped state", async () => { const settings = createSettings(); const state = {