Skip to content

Commit ff61db3

Browse files
author
王璨
committed
test: update permission prompt tests for canNavigateMenu and image input
1 parent 67bca65 commit ff61db3

1 file changed

Lines changed: 71 additions & 6 deletions

File tree

tests/ui/permission-prompt.test.ts

Lines changed: 71 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,32 @@ describe("permission prompt navigation", () => {
3232
expect(findPermOptionByKey("i")?.value).toBe("explain");
3333
});
3434

35-
it("debounces rapid menu navigation", () => {
36-
const canNavigateMenu = TuiApp.prototype["canNavigateMenu"] as (this: { menuNavDebounceUntil: number }, now?: number) => boolean;
37-
const state = { menuNavDebounceUntil: 0 };
35+
it("deduplicates rapid repeated menu navigation in the same direction", () => {
36+
const canNavigateMenu = TuiApp.prototype["canNavigateMenu"] as (this: { lastMenuNavDirection: "up" | "down" | null; lastMenuNavAt: number }, direction: "up" | "down", now?: number) => boolean;
37+
const state = { lastMenuNavDirection: null, lastMenuNavAt: 0 };
3838

3939
vi.spyOn(Date, "now")
4040
.mockReturnValueOnce(100)
4141
.mockReturnValueOnce(120)
4242
.mockReturnValueOnce(220);
4343

44-
expect(canNavigateMenu.call(state)).toBe(true);
45-
expect(canNavigateMenu.call(state)).toBe(false);
46-
expect(canNavigateMenu.call(state)).toBe(true);
44+
expect(canNavigateMenu.call(state, "down")).toBe(true);
45+
expect(canNavigateMenu.call(state, "down")).toBe(false);
46+
expect(canNavigateMenu.call(state, "down")).toBe(true);
47+
});
48+
49+
it("allows immediate direction changes in menu navigation", () => {
50+
const canNavigateMenu = TuiApp.prototype["canNavigateMenu"] as (this: { lastMenuNavDirection: "up" | "down" | null; lastMenuNavAt: number }, direction: "up" | "down", now?: number) => boolean;
51+
const state = { lastMenuNavDirection: null, lastMenuNavAt: 0 };
52+
53+
vi.spyOn(Date, "now")
54+
.mockReturnValueOnce(100)
55+
.mockReturnValueOnce(120)
56+
.mockReturnValueOnce(140);
57+
58+
expect(canNavigateMenu.call(state, "down")).toBe(true);
59+
expect(canNavigateMenu.call(state, "up")).toBe(true);
60+
expect(canNavigateMenu.call(state, "down")).toBe(true);
4761
});
4862

4963
it("submits input idea even while a tool call is waiting", () => {
@@ -56,6 +70,7 @@ describe("permission prompt navigation", () => {
5670
const state = {
5771
processing: true,
5872
permissionExplainMode: true,
73+
pendingImages: [],
5974
pendingPermissionContext: { toolName: "write_file", args: { path: "/tmp/test.json" } },
6075
editor: { setText: vi.fn() },
6176
resolvePermissionChoice,
@@ -104,4 +119,54 @@ describe("permission prompt navigation", () => {
104119
expect(state.processing).toBe(true);
105120
expect(state.editor.disableSubmit).toBe(false);
106121
});
122+
123+
it("submits image-only messages", () => {
124+
const handleSubmit = TuiApp.prototype["handleSubmit"] as (this: any, text: string) => void;
125+
const prompt = vi.fn().mockResolvedValue(undefined);
126+
const state = {
127+
pendingImages: [{ type: "image", data: "abcd", mimeType: "image/png" }],
128+
processing: false,
129+
permissionExplainMode: false,
130+
editor: { setText: vi.fn() },
131+
deps: {
132+
agent: { prompt },
133+
modelSupportsImages: true,
134+
modelNeedsOcr: false,
135+
},
136+
conversation: { addInfo: vi.fn() },
137+
addUserMessage: vi.fn(),
138+
setProcessing: vi.fn(),
139+
updateImageStatus: vi.fn(),
140+
addError: vi.fn(),
141+
stop: vi.fn(),
142+
};
143+
144+
handleSubmit.call(state, "");
145+
146+
expect(state.editor.setText).toHaveBeenCalledWith("");
147+
expect(state.addUserMessage).toHaveBeenCalledWith(expect.stringContaining("1 image(s) attached"));
148+
expect(state.setProcessing).toHaveBeenCalledWith(true);
149+
expect(state.pendingImages).toEqual([]);
150+
expect(state.updateImageStatus).toHaveBeenCalled();
151+
expect(prompt).toHaveBeenCalledWith("", [
152+
{ type: "image", data: "abcd", mimeType: "image/png" },
153+
]);
154+
});
155+
156+
it("keeps empty submit as a no-op when there is no text or image", () => {
157+
const handleSubmit = TuiApp.prototype["handleSubmit"] as (this: any, text: string) => void;
158+
const state = {
159+
pendingImages: [],
160+
editor: { setText: vi.fn() },
161+
deps: { agent: { prompt: vi.fn() } },
162+
addUserMessage: vi.fn(),
163+
setProcessing: vi.fn(),
164+
};
165+
166+
handleSubmit.call(state, "");
167+
168+
expect(state.editor.setText).not.toHaveBeenCalled();
169+
expect(state.addUserMessage).not.toHaveBeenCalled();
170+
expect(state.setProcessing).not.toHaveBeenCalled();
171+
});
107172
});

0 commit comments

Comments
 (0)