test(FN-4661): complete Step 5 — cover unread indicators in chat views

Fusion-Task-Id: FN-4661
Fusion-Task-Lineage: 39553dc3-4e7d-4398-b03f-24fa2edb9e20
This commit is contained in:
Fusion
2026-05-15 15:10:48 -07:00
committed by gsxdsm
parent 87c5e1dbfa
commit f0cd9eb3b7
2 changed files with 104 additions and 0 deletions

View File

@@ -755,6 +755,63 @@ describe("ChatView — rooms (FN-3805..FN-3811 contract)", () => {
});
});
it("renders unread dots for unread direct sessions and hides dot for active session", async () => {
const selectSession = vi.fn();
const sessionA: ChatSessionInfo = {
...activeSession,
id: "session-a",
title: "Session A",
updatedAt: "2026-04-08T00:00:00.000Z",
lastMessageAt: "2026-04-08T00:00:00.000Z",
};
const sessionB: ChatSessionInfo = {
...activeSession,
id: "session-b",
title: "Session B",
updatedAt: "2026-04-08T01:00:00.000Z",
lastMessageAt: "2026-04-08T01:00:00.000Z",
};
localStorage.setItem("fusion:chat-scope", "direct");
localStorage.setItem("kb:proj-123:fusion:chat-unread:direct", JSON.stringify({ "session-a": "2026-04-08T00:00:00.000Z" }));
setup({
sessions: [sessionA, sessionB],
filteredSessions: [sessionA, sessionB],
activeSession: sessionA,
selectSession,
});
render(<ChatView projectId="proj-123" addToast={vi.fn()} experimentalFeatures={{ chatRooms: true }} />);
expect(screen.queryByTestId("chat-unread-dot-session-a")).toBeNull();
expect(screen.getByTestId("chat-unread-dot-session-b")).toBeInTheDocument();
await userEvent.click(screen.getByTestId("chat-session-session-b"));
expect(selectSession).toHaveBeenCalledWith("session-b");
expect(localStorage.getItem("kb:proj-123:fusion:chat-unread:direct")).toContain("session-b");
});
it("renders unread dots for unread rooms", () => {
localStorage.setItem("fusion:chat-scope", "rooms");
localStorage.setItem("kb:proj-123:fusion:chat-unread:rooms", JSON.stringify({ "room-a": "2026-04-08T00:00:00.000Z" }));
const roomB = {
...roomA,
id: "room-b",
name: "Room B",
slug: "room-b",
updatedAt: "2026-04-08T01:00:00.000Z",
};
setup({}, { rooms: [roomA, roomB], activeRoom: roomA });
render(<ChatView projectId="proj-123" addToast={vi.fn()} experimentalFeatures={{ chatRooms: true }} />);
expect(screen.queryByTestId("chat-unread-dot-room-a")).toBeNull();
expect(screen.getByTestId("chat-unread-dot-room-b")).toBeInTheDocument();
});
it("keeps direct mode behavior unchanged when rooms are enabled", async () => {
localStorage.setItem("fusion:chat-scope", "direct");
const addToast = vi.fn();

View File

@@ -178,6 +178,53 @@ describe("QuickChatFAB session-first UX", () => {
expect(screen.getByTestId("quick-chat-session-option-session-agent")).toBeInTheDocument();
});
it("renders unread dots for unread sessions and hides active session dot", async () => {
localStorage.setItem(
"kb:proj-1:fusion:chat-unread:direct",
JSON.stringify({ "session-model": "2026-05-15T00:00:00.000Z" }),
);
render(<QuickChatFAB addToast={vi.fn()} projectId="proj-1" />);
fireEvent.click(screen.getByTestId("quick-chat-fab"));
fireEvent.click(await screen.findByTestId("quick-chat-session-dropdown-trigger"));
expect(screen.queryByTestId("quick-chat-unread-dot-session-model")).toBeNull();
expect(screen.getByTestId("quick-chat-unread-dot-session-agent")).toBeInTheDocument();
});
it("renders unread dots for unread rooms", async () => {
const selectRoom = vi.fn();
mockUseAppSettings.mockReturnValue({ experimentalFeatures: { chatRooms: true } } as ReturnType<typeof useAppSettings>);
mockUseChatRooms.mockReturnValue({
rooms: [
{ id: "room-1", name: "engineering", slug: "engineering", memberCount: 2, createdAt: new Date().toISOString(), updatedAt: "2026-05-15T00:00:00.000Z" },
{ id: "room-2", name: "support", slug: "support", memberCount: 2, createdAt: new Date().toISOString(), updatedAt: "2026-05-15T01:00:00.000Z" },
],
roomsLoading: false,
roomsError: null,
activeRoom: { id: "room-1", name: "engineering", slug: "engineering", memberCount: 2, createdAt: new Date().toISOString(), updatedAt: "2026-05-15T00:00:00.000Z" },
activeRoomMembers: [],
messages: [],
messagesLoading: false,
selectRoom,
createRoom: vi.fn(),
deleteRoom: vi.fn(),
sendRoomMessage: vi.fn(),
refreshRooms: vi.fn(),
});
localStorage.setItem(
"kb:proj-1:fusion:chat-unread:rooms",
JSON.stringify({ "room-1": "2026-05-15T00:00:00.000Z" }),
);
render(<QuickChatFAB addToast={vi.fn()} projectId="proj-1" />);
fireEvent.click(screen.getByTestId("quick-chat-fab"));
fireEvent.click(await screen.findByTestId("quick-chat-session-dropdown-trigger"));
expect(screen.queryByTestId("quick-chat-unread-dot-room-1")).toBeNull();
expect(screen.getByTestId("quick-chat-unread-dot-room-2")).toBeInTheDocument();
});
it("does not render room options or group labels when chat rooms are disabled", async () => {
render(<QuickChatFAB addToast={vi.fn()} projectId="proj-1" />);
fireEvent.click(screen.getByTestId("quick-chat-fab"));