Skip to content
Source
Sign inSign up

chatRouteCommands.browser.test.ts

67 lines2.4 KB

1import type { AnyRouter } from "@tanstack/react-router";
2import { describe, expect, it } from "vite-plus/test";
3​
4import { useThreadSelectionStore } from "../threadSelectionStore";
5import { installChatRouteCommands } from "./chatRouteCommands";
6​
7type Match = { readonly routeId: string; readonly pathname: string };
8​
9function routerAt(matches: Match[]) {
10 const state = { matches: matches.map((match) => ({ ...match, params: {} })) };
11 return {
12 router: { state } as unknown as AnyRouter,
13 navigate: (next: Match[]) => {
14 state.matches = next.map((match) => ({ ...match, params: {} }));
15 },
16 };
18​
19const CHAT: Match[] = [
20 { routeId: "__root__", pathname: "/" },
21 { routeId: "/_chat", pathname: "/" },
22];
23​
24function pressEscape(): KeyboardEvent {
25 const event = new KeyboardEvent("keydown", { key: "Escape", cancelable: true, bubbles: true });
26 window.dispatchEvent(event);
27 return event;
29​
30function selectThread(threadKey: string) {
31 useThreadSelectionStore.getState().clearSelection();
32 useThreadSelectionStore.getState().toggleThread(threadKey);
34​
35describe("chat route commands", () => {
36 it("clears a selection made after install, reading the store at keypress time", () => {
37 const { router } = routerAt(CHAT);
38 using stack = new DisposableStack();
39 stack.defer(installChatRouteCommands(router));
40 stack.defer(() => useThreadSelectionStore.getState().clearSelection());
41​
42 selectThread("env:thread-1");
43 const event = pressEscape();
44​
45 expect(event.defaultPrevented).toBe(true);
46 expect(useThreadSelectionStore.getState().selectedThreadKeys.size).toBe(0);
47 // With nothing selected, Escape is left for other handlers.
48 expect(pressEscape().defaultPrevented).toBe(false);
49 });
50​
51 it("stays out of the way off the chat route and under modal pages", () => {
52 const { router, navigate } = routerAt([{ routeId: "__root__", pathname: "/pair" }]);
53 using stack = new DisposableStack();
54 stack.defer(installChatRouteCommands(router));
55 stack.defer(() => useThreadSelectionStore.getState().clearSelection());
56 selectThread("env:thread-1");
57​
58 expect(pressEscape().defaultPrevented).toBe(false);
59​
60 navigate([...CHAT, { routeId: "/_chat/settings", pathname: "/settings" }]);
61 expect(pressEscape().defaultPrevented).toBe(false);
62 expect(useThreadSelectionStore.getState().selectedThreadKeys.size).toBe(1);
63​
64 navigate(CHAT);
65 expect(pressEscape().defaultPrevented).toBe(true);
66 });
67});