85820e4a43
* fix(web): warn when pasted attachment is too large * test(web): provide toast context to chat input tests * fix(web): warn when browser image paste lacks file data * fix(web): warn about oversized new task attachments * fix(web): keep toasts above modal overlays * fix(web): handle file-list-only dialog pastes * fix(web): avoid parsing clipboard HTML * fix(web): handle attachment paste edge cases * fix(web): improve attachment limit feedback * fix(web): show aggregate attachment limit feedback
112 lines
3.8 KiB
TypeScript
112 lines
3.8 KiB
TypeScript
import React, { createRef } from "react";
|
|
import { renderHook } from "@testing-library/react";
|
|
import { describe, expect, it, vi } from "vitest";
|
|
import { ToastProvider } from "@/components/toast-provider";
|
|
import { shouldShowChatFocusHint, useChatInputContainer } from "./use-chat-input-container";
|
|
import type { ChatInputContainerHandle } from "./chat-input-container";
|
|
|
|
function renderInputState(overrides: Partial<Parameters<typeof useChatInputContainer>[0]> = {}) {
|
|
return renderHook(
|
|
() =>
|
|
useChatInputContainer({
|
|
ref: createRef<ChatInputContainerHandle>(),
|
|
sessionId: "session-1",
|
|
isSending: false,
|
|
isStarting: false,
|
|
isPreparingEnvironment: false,
|
|
isMoving: false,
|
|
isFailed: false,
|
|
needsRecovery: false,
|
|
executorUnavailable: false,
|
|
isAgentBusy: false,
|
|
hasAgentCommands: true,
|
|
placeholder: undefined,
|
|
contextItems: [],
|
|
pendingClarification: null,
|
|
onClarificationResolved: undefined,
|
|
pendingCommentsByFile: undefined,
|
|
hasContextComments: false,
|
|
showRequestChangesTooltip: false,
|
|
onRequestChangesTooltipDismiss: undefined,
|
|
onSubmit: vi.fn(),
|
|
...overrides,
|
|
}),
|
|
{
|
|
wrapper: ({ children }) => React.createElement(ToastProvider, null, children),
|
|
},
|
|
);
|
|
}
|
|
|
|
describe("useChatInputContainer", () => {
|
|
it("disables the editor while the session is still STARTING", () => {
|
|
// The editor must stay uneditable until the agent reaches RUNNING — if
|
|
// the user can press Cmd+Enter mid-startup, the backend rejects with
|
|
// "Failed to send message to agent" because the agent process isn't
|
|
// ready yet. This is the regression from earlier rounds where the e2e
|
|
// quick-chat suite kept failing on race conditions.
|
|
const { result } = renderInputState({ isStarting: true });
|
|
|
|
expect(result.current.isDisabled).toBe(true);
|
|
expect(result.current.submitDisabled).toBe(true);
|
|
expect(result.current.submitDisabledReason).toBeUndefined();
|
|
});
|
|
|
|
it("surfaces the setup tooltip only while a container/sandbox is preparing", () => {
|
|
const { result } = renderInputState({
|
|
isStarting: true,
|
|
isPreparingEnvironment: true,
|
|
});
|
|
|
|
expect(result.current.submitDisabledReason).toBe("The agent is still being set up.");
|
|
});
|
|
|
|
it("keeps queueing enabled for an interactive clarification during stale startup", () => {
|
|
const { result } = renderInputState({
|
|
isStarting: true,
|
|
isPreparingEnvironment: true,
|
|
placeholder: "Queue instructions while the question is pending...",
|
|
pendingClarification: { id: "clarification-1" } as never,
|
|
onClarificationResolved: vi.fn(),
|
|
});
|
|
|
|
expect(result.current.isDisabled).toBe(false);
|
|
expect(result.current.submitDisabled).toBe(false);
|
|
expect(result.current.submitDisabledReason).toBeUndefined();
|
|
expect(result.current.inputPlaceholder).toBe(
|
|
"Queue instructions while the question is pending...",
|
|
);
|
|
});
|
|
});
|
|
|
|
describe("shouldShowChatFocusHint", () => {
|
|
it("hides the hint when a blurred editor has draft text", () => {
|
|
expect(
|
|
shouldShowChatFocusHint({
|
|
isInputFocused: false,
|
|
value: "halle from chat input",
|
|
hasClarification: false,
|
|
hasPendingComments: false,
|
|
}),
|
|
).toBe(false);
|
|
});
|
|
|
|
it("shows the hint only for an empty blurred editor without blocking overlays", () => {
|
|
expect(
|
|
shouldShowChatFocusHint({
|
|
isInputFocused: false,
|
|
value: " ",
|
|
hasClarification: false,
|
|
hasPendingComments: false,
|
|
}),
|
|
).toBe(true);
|
|
expect(
|
|
shouldShowChatFocusHint({
|
|
isInputFocused: true,
|
|
value: "",
|
|
hasClarification: false,
|
|
hasPendingComments: false,
|
|
}),
|
|
).toBe(false);
|
|
});
|
|
});
|