mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
99 lines
2.6 KiB
TypeScript
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");
|
|
});
|
|
});
|
|
});
|