FN-5884: preserve quick chat session across reopens
Keep quick chat warm and restore the last opened conversation per project. - persist the active quick chat session id in per-project local storage and restore it before falling back to latest activity - retain in-memory quick chat state across close/reopen while resetting chat state correctly when the project changes - add storage, hook, and FAB coverage for restored sessions, warm reopen behavior, and project switching; document the updated quick chat behavior Files changed: docs/dashboard-guide.md | 3 +- packages/dashboard/app/components/QuickChatFAB.tsx | 29 ++++-- .../app/components/__tests__/QuickChatFAB.test.tsx | 112 +++++++++++++++++++-- .../__tests__/quickChatLastSessionStorage.test.ts | 55 ++++++++++ .../app/hooks/__tests__/useQuickChat.test.ts | 70 +++++++++++++ .../app/hooks/quickChatLastSessionStorage.ts | 41 ++++++++ packages/dashboard/app/hooks/useQuickChat.ts | 25 +++++ 7 files changed, 319 insertions(+), 16 deletions(-) Fusion-Task-Id: FN-5884 Fusion-Task-Lineage: 4d689611-1824-41db-8fc2-d543407316ff
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import {
|
||||
getPersistedLastQuickChatSessionId,
|
||||
removePersistedLastQuickChatSessionId,
|
||||
setPersistedLastQuickChatSessionId,
|
||||
} from "../quickChatLastSessionStorage";
|
||||
|
||||
describe("quickChatLastSessionStorage", () => {
|
||||
beforeEach(() => {
|
||||
localStorage.clear();
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
it("stores and retrieves the last quick chat session id per project", () => {
|
||||
setPersistedLastQuickChatSessionId("proj-123", "session-123");
|
||||
|
||||
expect(getPersistedLastQuickChatSessionId("proj-123")).toBe("session-123");
|
||||
expect(localStorage.getItem("fusion:quick-chat-last-session:proj-123")).toBe("session-123");
|
||||
});
|
||||
|
||||
it("uses a default storage bucket when project id is missing", () => {
|
||||
setPersistedLastQuickChatSessionId(undefined, "session-default");
|
||||
|
||||
expect(getPersistedLastQuickChatSessionId()).toBe("session-default");
|
||||
expect(localStorage.getItem("fusion:quick-chat-last-session:default")).toBe("session-default");
|
||||
});
|
||||
|
||||
it("removes persisted session ids per project", () => {
|
||||
setPersistedLastQuickChatSessionId("proj-123", "session-123");
|
||||
|
||||
removePersistedLastQuickChatSessionId("proj-123");
|
||||
|
||||
expect(getPersistedLastQuickChatSessionId("proj-123")).toBeNull();
|
||||
});
|
||||
|
||||
it("returns null when nothing is saved", () => {
|
||||
expect(getPersistedLastQuickChatSessionId("proj-123")).toBeNull();
|
||||
});
|
||||
|
||||
it("swallows localStorage failures", () => {
|
||||
vi.spyOn(Storage.prototype, "setItem").mockImplementation(() => {
|
||||
throw new Error("quota exceeded");
|
||||
});
|
||||
vi.spyOn(Storage.prototype, "getItem").mockImplementation(() => {
|
||||
throw new Error("blocked");
|
||||
});
|
||||
vi.spyOn(Storage.prototype, "removeItem").mockImplementation(() => {
|
||||
throw new Error("blocked");
|
||||
});
|
||||
|
||||
expect(() => setPersistedLastQuickChatSessionId("proj-123", "session-123")).not.toThrow();
|
||||
expect(getPersistedLastQuickChatSessionId("proj-123")).toBeNull();
|
||||
expect(() => removePersistedLastQuickChatSessionId("proj-123")).not.toThrow();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user