diff --git a/web/src/app.tsx b/web/src/app.tsx index a5e58a9..c8bd44d 100644 --- a/web/src/app.tsx +++ b/web/src/app.tsx @@ -1,5 +1,5 @@ import { lazy, Suspense } from "react"; -import { BrowserRouter, Navigate, Route, Routes } from "react-router-dom"; +import { createBrowserRouter, createRoutesFromElements, Navigate, Route, RouterProvider } from "react-router-dom"; import { RequireAuth } from "./auth/require-auth"; import { LoginPage } from "./auth/login-page"; @@ -29,55 +29,57 @@ function FormFallback() { return
Loading…
; } -export function App() { - return ( - - - } /> - }> - }> +const router = createBrowserRouter( + createRoutesFromElements( + <> + } /> + }> + }> + }> + + + } + /> + }> + } /> }> - + } /> - }> - } /> - }> - - - } - /> - - }> - } /> - } /> - - }> - } /> - } /> - - } /> - } /> - }> - - - } - /> - } /> + }> + } /> + } /> + + }> + } /> + } /> + + } /> + } /> + }> + + + } + /> + } /> - } /> - - - ); + + } /> + , + ), +); + +export function App() { + return ; } diff --git a/web/src/search/search.test.tsx b/web/src/search/search.test.tsx index 66ba609..f69fea6 100644 --- a/web/src/search/search.test.tsx +++ b/web/src/search/search.test.tsx @@ -1,8 +1,9 @@ import { expect, test } from "vitest"; -import { screen, waitFor, within } from "@testing-library/react"; +import { render, screen, waitFor, within } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { http, HttpResponse } from "msw"; -import { Route, Routes } from "react-router-dom"; +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import { createMemoryRouter, Route, RouterProvider, Routes } from "react-router-dom"; import { server } from "../test/server"; import { renderApp } from "../test/render"; @@ -10,6 +11,7 @@ import { amphora } from "../test/fixtures"; import { SearchPage } from "./search-page"; import { SelectSearchPrompt } from "./select-search-prompt"; import { ObjectDetail } from "../objects/object-detail"; +import "../i18n"; function tree() { return ( @@ -22,6 +24,35 @@ function tree() { ); } +// The search rows are s. Under the shared `renderApp` harness the test +// subtree lives in a descendant under a catch-all `*` data route, where +// the data router does not intercept the link click (it falls through to a real +// browser navigation that jsdom rejects). Mounting the search routes as real +// data-router routes lets RouterProvider intercept the NavLink, which is the +// data-router equivalent of the old MemoryRouter behavior. +function renderSearchRouter(route = "/search") { + const qc = new QueryClient({ defaultOptions: { queries: { retry: false } } }); + const router = createMemoryRouter( + [ + { + path: "/search", + element: , + children: [ + { index: true, element: }, + { path: ":id", element: }, + ], + }, + ], + { initialEntries: [route] }, + ); + + return render( + + + , + ); +} + test("typing searches and renders highlighted rich rows", async () => { renderApp(tree(), { route: "/search" }); await userEvent.type(screen.getByLabelText(/search the collection/i), "bronze"); @@ -69,7 +100,7 @@ test("empty query shows the prompt; zero results shows empty", async () => { }); test("clicking a result shows the object in the detail pane", async () => { - renderApp(tree(), { route: "/search" }); + renderSearchRouter(); await userEvent.type(screen.getByLabelText(/search the collection/i), "bronze"); await userEvent.click(await screen.findByText("Bronze figurine")); diff --git a/web/src/test/render.tsx b/web/src/test/render.tsx index b9f5edd..abf83fa 100644 --- a/web/src/test/render.tsx +++ b/web/src/test/render.tsx @@ -1,16 +1,17 @@ import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { render } from "@testing-library/react"; import type { ReactElement } from "react"; -import { MemoryRouter } from "react-router-dom"; +import { createMemoryRouter, RouterProvider } from "react-router-dom"; import "../i18n"; export function renderApp(ui: ReactElement, { route = "/" } = {}) { const qc = new QueryClient({ defaultOptions: { queries: { retry: false } } }); + const router = createMemoryRouter([{ path: "*", element: ui }], { initialEntries: [route] }); return render( - {ui} + , ); }