Files
coder/site/src/pages/AgentsPage/components/ChatMessageInput/ChatMessageInput.test.tsx
T

99 lines
2.6 KiB
TypeScript

import { render, screen, waitFor } from "@testing-library/react";
import { type FC, useLayoutEffect, useRef, useState } from "react";
import { describe, expect, it } from "vitest";
import { ChatMessageInput, type ChatMessageInputRef } from "./ChatMessageInput";
const InitialValueHarness: FC<{ initialValue: string }> = ({
initialValue,
}) => {
const inputRef = useRef<ChatMessageInputRef>(null);
const [observedValue, setObservedValue] = useState("");
useLayoutEffect(() => {
setObservedValue(inputRef.current?.getValue() ?? "");
}, []);
return (
<>
<div data-testid="observed-value">{observedValue}</div>
<ChatMessageInput
ref={inputRef}
initialValue={initialValue}
aria-label="Chat message input"
/>
</>
);
};
const QueuedReplacementHarness: FC<{
initialValue: string;
replacementValue: string;
}> = ({ initialValue, replacementValue }) => {
const inputRef = useRef<ChatMessageInputRef>(null);
const [observedValue, setObservedValue] = useState("");
useLayoutEffect(() => {
inputRef.current?.setValue(replacementValue);
setObservedValue(inputRef.current?.getValue() ?? "");
}, [replacementValue]);
return (
<>
<div data-testid="observed-value">{observedValue}</div>
<ChatMessageInput
ref={inputRef}
initialValue={initialValue}
aria-label="Chat message input"
/>
</>
);
};
describe("ChatMessageInput", () => {
it("returns the initial draft before the editor visually hydrates", async () => {
render(<InitialValueHarness initialValue="persisted draft" />);
expect(screen.getByTestId("observed-value")).toHaveTextContent(
"persisted draft",
);
await waitFor(() => {
expect(screen.getByTestId("chat-message-input").textContent).toBe(
"persisted draft",
);
});
});
it("queues setValue calls made before the editor is ready", async () => {
render(
<QueuedReplacementHarness
initialValue="persisted draft"
replacementValue="queued replacement"
/>,
);
expect(screen.getByTestId("observed-value")).toHaveTextContent(
"queued replacement",
);
await waitFor(() => {
expect(screen.getByTestId("chat-message-input").textContent).toBe(
"queued replacement",
);
});
});
it("returns updated content even without an external onChange prop", async () => {
const inputRef = { current: null as ChatMessageInputRef | null };
render(<ChatMessageInput ref={inputRef} aria-label="Chat message input" />);
await waitFor(() => {
expect(inputRef.current).not.toBeNull();
});
inputRef.current?.insertText("typed content");
await waitFor(() => {
expect(inputRef.current?.getValue()).toBe("typed content");
});
});
});