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 (
);
};
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);
});
});