/* eslint-disable @next/next/no-img-element */ import "@testing-library/jest-dom"; import React from "react"; import { render } from "@testing-library/react"; import { AgentWorkspace } from "./AgentWorkspace"; import type { Message } from "./GlobalChatbox.types"; const renderCounts = new Map(); jest.mock("next/image", () => ({ __esModule: true, default: (props: React.ImgHTMLAttributes) => {props.alt, })); jest.mock("framer-motion", () => ({ AnimatePresence: ({ children }: { children: React.ReactNode }) => <>{children}, motion: { div: ({ children, ...props }: React.HTMLAttributes) =>
{children}
, }, })); jest.mock("./GlobalChatbox.parts", () => ({ TypingIndicator: () =>
typing
, })); jest.mock("./AgentTurn", () => ({ AgentTurn: ({ message }: { message: Message }) => { renderCounts.set(message.id, (renderCounts.get(message.id) ?? 0) + 1); return
{message.content}
; }, })); describe("AgentWorkspace", () => { const defaultProps = { branchGroups: [], branchTransition: null, bottomRef: { current: null }, speakingMessageId: null, speechState: "idle" as const, onSpeak: jest.fn(), onPauseSpeech: jest.fn(), onResumeSpeech: jest.fn(), onStopSpeech: jest.fn(), isTtsSupported: false, onRegenerate: jest.fn(), onEditResubmit: jest.fn(), onCycleBranch: jest.fn(), onReplyPermission: jest.fn(), }; beforeEach(() => { renderCounts.clear(); }); it("keeps stable history turns from re-rendering while the last assistant message streams", () => { const userMessage: Message = { id: "user-1", role: "user", content: "question", }; const assistantHistoryMessage: Message = { id: "assistant-1", role: "assistant", content: "stable answer", }; const streamingMessage: Message = { id: "assistant-2", role: "assistant", content: "partial", }; const { rerender } = render( , ); const updatedStreamingMessage: Message = { ...streamingMessage, content: "partial with more tokens", }; rerender( , ); expect(renderCounts.get("user-1")).toBe(1); expect(renderCounts.get("assistant-1")).toBe(1); expect(renderCounts.get("assistant-2")).toBe(2); }); });