mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-11 03:38:38 +00:00
fix: address issue #24279
This commit is contained in:
parent
50f88c8642
commit
55b27265ea
2 changed files with 177 additions and 4 deletions
|
|
@ -0,0 +1,173 @@
|
|||
import { renderHook } from "@testing-library/react";
|
||||
import { act } from "react";
|
||||
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
||||
import { useKeyboardNavigation } from "./useKeyboardNavigation";
|
||||
import { LogEntry } from "../columns";
|
||||
|
||||
function makeLog(request_id: string): LogEntry {
|
||||
return {
|
||||
request_id,
|
||||
api_key: "key",
|
||||
team_id: "team",
|
||||
model: "gpt-4",
|
||||
model_id: "model-id",
|
||||
call_type: "completion",
|
||||
spend: 0,
|
||||
total_tokens: 0,
|
||||
prompt_tokens: 0,
|
||||
completion_tokens: 0,
|
||||
startTime: "2024-01-01T00:00:00Z",
|
||||
endTime: "2024-01-01T00:00:01Z",
|
||||
cache_hit: "False",
|
||||
messages: [],
|
||||
response: "",
|
||||
};
|
||||
}
|
||||
|
||||
const logA = makeLog("log-a");
|
||||
const logB = makeLog("log-b");
|
||||
const logC = makeLog("log-c");
|
||||
const allLogs = [logA, logB, logC];
|
||||
|
||||
describe("useKeyboardNavigation", () => {
|
||||
let onClose: ReturnType<typeof vi.fn>;
|
||||
let onSelectLog: ReturnType<typeof vi.fn>;
|
||||
|
||||
beforeEach(() => {
|
||||
onClose = vi.fn();
|
||||
onSelectLog = vi.fn();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
const fireKey = (key: string) => {
|
||||
act(() => {
|
||||
window.dispatchEvent(new KeyboardEvent("keydown", { key, bubbles: true }));
|
||||
});
|
||||
};
|
||||
|
||||
it("J key calls selectNextLog (moves to next/down in list)", () => {
|
||||
renderHook(() =>
|
||||
useKeyboardNavigation({
|
||||
isOpen: true,
|
||||
currentLog: logA,
|
||||
allLogs,
|
||||
onClose,
|
||||
onSelectLog,
|
||||
})
|
||||
);
|
||||
|
||||
fireKey("j");
|
||||
expect(onSelectLog).toHaveBeenCalledWith(logB);
|
||||
});
|
||||
|
||||
it("J (uppercase) key calls selectNextLog", () => {
|
||||
renderHook(() =>
|
||||
useKeyboardNavigation({
|
||||
isOpen: true,
|
||||
currentLog: logA,
|
||||
allLogs,
|
||||
onClose,
|
||||
onSelectLog,
|
||||
})
|
||||
);
|
||||
|
||||
fireKey("J");
|
||||
expect(onSelectLog).toHaveBeenCalledWith(logB);
|
||||
});
|
||||
|
||||
it("K key calls selectPreviousLog (moves to previous/up in list)", () => {
|
||||
renderHook(() =>
|
||||
useKeyboardNavigation({
|
||||
isOpen: true,
|
||||
currentLog: logB,
|
||||
allLogs,
|
||||
onClose,
|
||||
onSelectLog,
|
||||
})
|
||||
);
|
||||
|
||||
fireKey("k");
|
||||
expect(onSelectLog).toHaveBeenCalledWith(logA);
|
||||
});
|
||||
|
||||
it("K (uppercase) key calls selectPreviousLog", () => {
|
||||
renderHook(() =>
|
||||
useKeyboardNavigation({
|
||||
isOpen: true,
|
||||
currentLog: logB,
|
||||
allLogs,
|
||||
onClose,
|
||||
onSelectLog,
|
||||
})
|
||||
);
|
||||
|
||||
fireKey("K");
|
||||
expect(onSelectLog).toHaveBeenCalledWith(logA);
|
||||
});
|
||||
|
||||
it("J key does not go past the last log", () => {
|
||||
renderHook(() =>
|
||||
useKeyboardNavigation({
|
||||
isOpen: true,
|
||||
currentLog: logC,
|
||||
allLogs,
|
||||
onClose,
|
||||
onSelectLog,
|
||||
})
|
||||
);
|
||||
|
||||
fireKey("j");
|
||||
expect(onSelectLog).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("K key does not go before the first log", () => {
|
||||
renderHook(() =>
|
||||
useKeyboardNavigation({
|
||||
isOpen: true,
|
||||
currentLog: logA,
|
||||
allLogs,
|
||||
onClose,
|
||||
onSelectLog,
|
||||
})
|
||||
);
|
||||
|
||||
fireKey("k");
|
||||
expect(onSelectLog).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("Escape key calls onClose", () => {
|
||||
renderHook(() =>
|
||||
useKeyboardNavigation({
|
||||
isOpen: true,
|
||||
currentLog: logA,
|
||||
allLogs,
|
||||
onClose,
|
||||
onSelectLog,
|
||||
})
|
||||
);
|
||||
|
||||
fireKey("Escape");
|
||||
expect(onClose).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("keys do nothing when drawer is closed", () => {
|
||||
renderHook(() =>
|
||||
useKeyboardNavigation({
|
||||
isOpen: false,
|
||||
currentLog: logA,
|
||||
allLogs,
|
||||
onClose,
|
||||
onSelectLog,
|
||||
})
|
||||
);
|
||||
|
||||
fireKey("j");
|
||||
fireKey("k");
|
||||
fireKey("Escape");
|
||||
expect(onSelectLog).not.toHaveBeenCalled();
|
||||
expect(onClose).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
|
@ -15,8 +15,8 @@ interface UseKeyboardNavigationProps {
|
|||
* Handles J/K for next/previous and Escape for close.
|
||||
*
|
||||
* Keyboard shortcuts:
|
||||
* - J: Navigate to previous log (up)
|
||||
* - K: Navigate to next log (down)
|
||||
* - J: Navigate to next log (down)
|
||||
* - K: Navigate to previous log (up)
|
||||
* - Escape: Close drawer
|
||||
*/
|
||||
export function useKeyboardNavigation({
|
||||
|
|
@ -41,11 +41,11 @@ export function useKeyboardNavigation({
|
|||
break;
|
||||
case KEY_J_LOWER:
|
||||
case KEY_J_UPPER:
|
||||
selectPreviousLog();
|
||||
selectNextLog();
|
||||
break;
|
||||
case KEY_K_LOWER:
|
||||
case KEY_K_UPPER:
|
||||
selectNextLog();
|
||||
selectPreviousLog();
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue