import { act, fireEvent, render, screen, waitFor } from "@testing-library/react"; import { createMemoryRouter, MemoryRouter, RouterProvider, useLocation } from "react-router-dom"; import { describe, expect, it } from "vitest"; import { type MemoFilter, MemoFilterProvider, parseFilterQuery, stringifyFilters, useMemoFilterContext, } from "@/contexts/MemoFilterContext"; import { BUILTIN_TASKS_VIEW_ID } from "@/lib/memo-views"; const expression = 'tags.exists(t, t.contains("50%, café & C++"))\n || space == null'; const Harness = () => { const { filters, setFilters, setMemoView, memoView } = useMemoFilterContext(); const location = useLocation(); return (
{JSON.stringify(filters)} {memoView} {location.search}
); }; describe("MemoFilterProvider", () => { it("restores CEL after URL synchronization, navigation history, and remount", async () => { const routes = [ { path: "*", element: ( ), }, ]; const router = createMemoryRouter(routes, { initialEntries: ["/inbox", "/explore"], initialIndex: 1 }); const rendered = render(); fireEvent.click(screen.getByRole("button", { name: "Search CEL" })); const expected: MemoFilter[] = [{ factor: "celSearch", value: expression }]; await waitFor(() => expect(parseFilterQuery(new URLSearchParams(router.state.location.search).get("filter"))).toEqual(expected)); const savedUrl = `/explore${router.state.location.search}`; await act(async () => { await router.navigate(-1); }); await waitFor(() => expect(screen.getByTestId("filters")).toHaveTextContent("[]")); await act(async () => { await router.navigate(1); }); await waitFor(() => expect(screen.getByTestId("filters")).toHaveTextContent(JSON.stringify(expected))); rendered.unmount(); render(); expect(screen.getByTestId("filters")).toHaveTextContent(JSON.stringify(expected)); expect(new URLSearchParams(router.state.location.search).get("filter")).toBe(stringifyFilters(expected)); }); it("keeps encoded values containing colons intact", () => { expect(parseFilterQuery("contentSearch:https://example.com:8080/path")).toEqual([ { factor: "contentSearch", value: "https://example.com:8080/path" }, ]); }); it("keeps search filters when selecting a view", () => { render( , ); fireEvent.click(screen.getByRole("button", { name: "Search plan" })); fireEvent.click(screen.getByRole("button", { name: "Select Tasks" })); expect(screen.getByTestId("filters")).toHaveTextContent('[{"factor":"contentSearch","value":"plan"}]'); expect(screen.getByTestId("memoView")).toHaveTextContent(BUILTIN_TASKS_VIEW_ID); }); });