/** * @file ConversationView.pushed.test.tsx * @description The server says a session's transcript grew * (`transcript_changed`): the chat showing that session reads the new lines * at once, and again within a short window after a burst — not at the hook * throttle's 1.5 s pace — while another session's notice fetches nothing. * @author Nguyễn Ngọc Trí Vĩ */ import { act, render, screen } from "@testing-library/react"; import { afterEach, describe, expect, it, vi } from "vitest"; import { ConversationView } from "../ConversationView"; import { api } from "../../../lib/api"; import { eventBus } from "../../../lib/eventBus"; vi.mock("../../../lib/api", async (importOriginal) => { const actual = await importOriginal>(); return { ...actual, api: { sessions: { transcripts: vi.fn(async () => ({ transcripts: [] })), transcript: vi.fn(async () => ({ messages: [ { type: "user", content: [{ type: "text", text: "hello" }], timestamp: "2026-10-21T00:00:00Z", }, ], total: 1, has_more: false, first_line: 1, last_line: 1, })), }, }, }; }); afterEach(() => { vi.useRealTimers(); vi.clearAllMocks(); }); const pushed = (session_id: string) => act(() => eventBus.publish({ type: "transcript_changed", data: { session_id } } as never)); const calls = () => vi.mocked(api.sessions.transcript).mock.calls.length; describe("ConversationView on transcript_changed", () => { it("reads its own session's new lines at once, and a burst within 300 ms", async () => { render(); await screen.findByText("hello"); vi.useFakeTimers(); const before = calls(); pushed("s1"); expect(calls()).toBe(before + 1); pushed("s1"); pushed("s1"); await act(async () => { await vi.advanceTimersByTimeAsync(350); }); expect(calls()).toBe(before + 2); }); it("ignores another session's transcript", async () => { render(); await screen.findByText("hello"); const before = calls(); pushed("s2"); await act(async () => {}); expect(calls()).toBe(before); }); });