From f7b4e749326e6e17dcd55d4bc78ae7cd681037bd Mon Sep 17 00:00:00 2001
From: Seydulla Narkulyyev <seydullanarkulyyev0@gmail.com>
Date: Tue, 22 Jul 2025 01:43:23 +0400
Subject: feat(cli):suggestion-navigation-shortcut (#3641)

Co-authored-by: N. Taylor Mullen <ntaylormullen@google.com>
---
 .../cli/src/ui/components/InputPrompt.test.tsx     | 77 ++++++++++++++++++++++
 1 file changed, 77 insertions(+)

(limited to 'packages/cli/src/ui/components/InputPrompt.test.tsx')

diff --git a/packages/cli/src/ui/components/InputPrompt.test.tsx b/packages/cli/src/ui/components/InputPrompt.test.tsx
index 886a6235..3f646cc6 100644
--- a/packages/cli/src/ui/components/InputPrompt.test.tsx
+++ b/packages/cli/src/ui/components/InputPrompt.test.tsx
@@ -221,6 +221,83 @@ describe('InputPrompt', () => {
     unmount();
   });
 
+  it('should call completion.navigateUp for both up arrow and Ctrl+P when suggestions are showing', async () => {
+    mockedUseCompletion.mockReturnValue({
+      ...mockCompletion,
+      showSuggestions: true,
+      suggestions: [
+        { label: 'memory', value: 'memory' },
+        { label: 'memcache', value: 'memcache' },
+      ],
+    });
+
+    props.buffer.setText('/mem');
+
+    const { stdin, unmount } = render(<InputPrompt {...props} />);
+    await wait();
+
+    // Test up arrow
+    stdin.write('\u001B[A'); // Up arrow
+    await wait();
+
+    stdin.write('\u0010'); // Ctrl+P
+    await wait();
+    expect(mockCompletion.navigateUp).toHaveBeenCalledTimes(2);
+    expect(mockCompletion.navigateDown).not.toHaveBeenCalled();
+
+    unmount();
+  });
+
+  it('should call completion.navigateDown for both down arrow and Ctrl+N when suggestions are showing', async () => {
+    mockedUseCompletion.mockReturnValue({
+      ...mockCompletion,
+      showSuggestions: true,
+      suggestions: [
+        { label: 'memory', value: 'memory' },
+        { label: 'memcache', value: 'memcache' },
+      ],
+    });
+    props.buffer.setText('/mem');
+
+    const { stdin, unmount } = render(<InputPrompt {...props} />);
+    await wait();
+
+    // Test down arrow
+    stdin.write('\u001B[B'); // Down arrow
+    await wait();
+
+    stdin.write('\u000E'); // Ctrl+N
+    await wait();
+    expect(mockCompletion.navigateDown).toHaveBeenCalledTimes(2);
+    expect(mockCompletion.navigateUp).not.toHaveBeenCalled();
+
+    unmount();
+  });
+
+  it('should NOT call completion navigation when suggestions are not showing', async () => {
+    mockedUseCompletion.mockReturnValue({
+      ...mockCompletion,
+      showSuggestions: false,
+    });
+    props.buffer.setText('some text');
+
+    const { stdin, unmount } = render(<InputPrompt {...props} />);
+    await wait();
+
+    stdin.write('\u001B[A'); // Up arrow
+    await wait();
+    stdin.write('\u001B[B'); // Down arrow
+    await wait();
+    stdin.write('\u0010'); // Ctrl+P
+    await wait();
+    stdin.write('\u000E'); // Ctrl+N
+    await wait();
+
+    expect(mockCompletion.navigateUp).not.toHaveBeenCalled();
+    expect(mockCompletion.navigateDown).not.toHaveBeenCalled();
+    unmount();
+  });
+
   describe('clipboard image paste', () => {
     beforeEach(() => {
       vi.mocked(clipboardUtils.clipboardHasImage).mockResolvedValue(false);
-- 
cgit v1.2.3

