authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-03-04 13:00:27-08:00
committergravatar for jmarminge@gmail.comJulius Marminge <jmarminge@gmail.com> 2026-03-05 10:20:34-08:00
log2d8ca4817593c2fda1ce0b16849fc9920591538f
tree625ac4c57c2ff5633f33bdd1891951beeb60cbe6
parent4ca4a1f99c346456bd9434e9ae4e77f31b2c7aaf

Use real TanStack router in ChatView browser tests

- Replace mocked router hooks with a memory router + RouterProvider - Render ChatView through a test route to exercise attachment height layout in realistic routing context

1 files changed, 28 insertions(+), 8 deletions(-)

apps/web/src/components/ChatView.browser.tsx+28-8
......@@ -1,6 +1,14 @@
11import "../index.css";
22
33import { type MessageId, type ThreadId } from "@t3tools/contracts";
4import {
5 Outlet,
6 RouterProvider,
7 createMemoryHistory,
8 createRootRoute,
9 createRoute,
10 createRouter,
11} from "@tanstack/react-router";
412import { createRoot, type Root } from "react-dom/client";
513import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
614
......@@ -10,7 +18,6 @@ import { estimateTimelineMessageHeight } from "./timelineHeight";
1018
1119const mocks = vi.hoisted(() => {
1220 return {
13 navigate: vi.fn(),
1421 markThreadVisited: vi.fn(),
1522 setThreadError: vi.fn(),
1623 setRuntimeMode: vi.fn(),
......@@ -67,12 +74,6 @@ const mocks = vi.hoisted(() => {
6774 };
6875});
6976
70vi.mock("@tanstack/react-router", () => ({
71 useNavigate: () => mocks.navigate,
72 useSearch: (options?: { select?: (params: Record<string, unknown>) => unknown }) =>
73 options?.select ? options.select({}) : {},
74}));
75
7677vi.mock("@tanstack/react-query", async () => {
7778 const actual = await vi.importActual<typeof import("@tanstack/react-query")>(
7879 "@tanstack/react-query",
......@@ -163,6 +164,24 @@ interface RenderMeasureOptions {
163164 targetMessageId: MessageId;
164165}
165166
167function createTestRouter(threadId: ThreadId) {
168 const rootRoute = createRootRoute({
169 component: () => <Outlet />,
170 });
171 const threadRoute = createRoute({
172 getParentRoute: () => rootRoute,
173 path: "/$threadId",
174 component: () => <ChatView threadId={threadId} />,
175 });
176 return createRouter({
177 routeTree: rootRoute.addChildren([threadRoute]),
178 history: createMemoryHistory({
179 initialEntries: [`/${threadId}`],
180 }),
181 context: {},
182 });
183}
184
166185function createThread(messages: ChatMessage[]): Thread {
167186 return {
168187 id: THREAD_ID,
......@@ -315,9 +334,10 @@ async function renderAndMeasureUserRow({
315334 document.body.append(host);
316335
317336 mocks.storeState.threads = [createThread(messages)];
337 const router = createTestRouter(THREAD_ID);
318338
319339 const root: Root = createRoot(host);
320 root.render(<ChatView threadId={THREAD_ID} />);
340 root.render(<RouterProvider router={router} />);
321341 await waitForLayout();
322342
323343 const scrollContainer = host.querySelector("div.overflow-y-auto.overscroll-y-contain");