99 lines
2.7 KiB
TypeScript
99 lines
2.7 KiB
TypeScript
/* 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<string, number>();
|
|
|
|
jest.mock("next/image", () => ({
|
|
__esModule: true,
|
|
default: (props: React.ImgHTMLAttributes<HTMLImageElement>) => <img {...props} alt={props.alt ?? ""} />,
|
|
}));
|
|
|
|
jest.mock("framer-motion", () => ({
|
|
AnimatePresence: ({ children }: { children: React.ReactNode }) => <>{children}</>,
|
|
motion: {
|
|
div: ({ children, ...props }: React.HTMLAttributes<HTMLDivElement>) => <div {...props}>{children}</div>,
|
|
},
|
|
}));
|
|
|
|
jest.mock("./GlobalChatbox.parts", () => ({
|
|
TypingIndicator: () => <div>typing</div>,
|
|
}));
|
|
|
|
jest.mock("./AgentTurn", () => ({
|
|
AgentTurn: ({ message }: { message: Message }) => {
|
|
renderCounts.set(message.id, (renderCounts.get(message.id) ?? 0) + 1);
|
|
return <div data-testid={`turn-${message.id}`}>{message.content}</div>;
|
|
},
|
|
}));
|
|
|
|
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(
|
|
<AgentWorkspace
|
|
{...defaultProps}
|
|
isStreaming
|
|
messages={[userMessage, assistantHistoryMessage, streamingMessage]}
|
|
/>,
|
|
);
|
|
|
|
const updatedStreamingMessage: Message = {
|
|
...streamingMessage,
|
|
content: "partial with more tokens",
|
|
};
|
|
|
|
rerender(
|
|
<AgentWorkspace
|
|
{...defaultProps}
|
|
isStreaming
|
|
messages={[userMessage, assistantHistoryMessage, updatedStreamingMessage]}
|
|
/>,
|
|
);
|
|
|
|
expect(renderCounts.get("user-1")).toBe(1);
|
|
expect(renderCounts.get("assistant-1")).toBe(1);
|
|
expect(renderCounts.get("assistant-2")).toBe(2);
|
|
});
|
|
});
|