MiniSearch / client /components /Pages /Main /Menu /MenuDrawer.test.tsx
github-actions[bot]
Sync from https://github.com/felladrin/MiniSearch
abf1288
Raw
History Blame Contribute Delete
4.23 kB
import { MantineProvider } from "@mantine/core";
import { render, screen, within } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { usePubSub } from "create-pubsub/react";
import { beforeEach, describe, expect, it, vi } from "vitest";
import {
menuExpandedAccordionsPubSub,
showFeatureTipsPubSub,
} from "@/modules/pubSub";
vi.mock("create-pubsub/react", () => ({
usePubSub: vi.fn(),
}));
vi.mock("./AISettings/AISettingsForm", () => ({
default: () => <div data-testid="ai-settings-form" />,
}));
vi.mock("./SearchSettingsForm", () => ({
default: () => <div data-testid="search-settings-form" />,
}));
vi.mock("./InterfaceSettingsForm", () => ({
default: () => <div data-testid="interface-settings-form" />,
}));
vi.mock("./VoiceSettingsForm", () => ({
default: () => <div data-testid="voice-settings-form" />,
}));
vi.mock("./ActionsForm", () => ({
default: () => <div data-testid="actions-form" />,
}));
vi.mock("@/components/Settings/HistorySettings", () => ({
default: () => <div data-testid="history-settings-form" />,
}));
interface MenuState {
expandedAccordions: string[];
showFeatureTips: boolean;
}
function createMenuState(overrides: Partial<MenuState> = {}): MenuState {
return {
expandedAccordions: [],
showFeatureTips: true,
...overrides,
};
}
function mockMenuState(state: MenuState) {
const setShowFeatureTips = vi.fn();
vi.mocked(usePubSub).mockImplementation((pubSub: unknown) => {
if (pubSub === menuExpandedAccordionsPubSub)
return [state.expandedAccordions, vi.fn()];
if (pubSub === showFeatureTipsPubSub)
return [state.showFeatureTips, setShowFeatureTips];
throw new Error("MenuDrawer.test.tsx: unexpected pubSub in usePubSub mock");
});
return { setShowFeatureTips };
}
async function renderMenuDrawer(state: MenuState) {
const handlers = mockMenuState(state);
const MenuDrawer = (await import("./MenuDrawer")).default;
const utils = render(
<MantineProvider>
<MenuDrawer opened onClose={vi.fn()} />
</MantineProvider>,
);
return { ...utils, ...handlers };
}
describe("MenuDrawer", () => {
beforeEach(() => {
vi.clearAllMocks();
});
it("renders a description under each accordion control", async () => {
await renderMenuDrawer(createMenuState());
const sections: Array<[title: string, description: string]> = [
["AI Settings", "AI responses, where inference runs, and reasoning"],
["Search Settings", "Text and image results, and how many to show"],
["Interface Settings", "Appearance and search-box input"],
["History Settings", "How long and how many searches to keep"],
["Voice Settings", "The voice used when reading answers aloud"],
["Actions", "Clear stored data and view the log"],
];
// Scoped to the control so the test fails if a description moves into the
// (keepMounted) panel, where it would no longer be visible while collapsed.
for (const [title, description] of sections) {
const control = screen.getByRole("button", { name: new RegExp(title) });
expect(within(control).getByText(description)).toBeInTheDocument();
}
});
it("shows the tips with the search URL when enabled", async () => {
await renderMenuDrawer(createMenuState({ showFeatureTips: true }));
expect(screen.getByText("Tips")).toBeInTheDocument();
expect(screen.getByText(/Search from anywhere/)).toBeInTheDocument();
expect(screen.getByText(/\/\?q=%s/)).toBeInTheDocument();
expect(
screen.getByText(/use the speaker button on an answer/),
).toBeInTheDocument();
});
it("hides the tips when showFeatureTips is false", async () => {
await renderMenuDrawer(createMenuState({ showFeatureTips: false }));
expect(screen.queryByText("Tips")).not.toBeInTheDocument();
});
it("persists the dismissal when the tips are closed", async () => {
const user = userEvent.setup();
const { setShowFeatureTips } = await renderMenuDrawer(
createMenuState({ showFeatureTips: true }),
);
await user.click(screen.getByRole("button", { name: "Dismiss tips" }));
expect(setShowFeatureTips).toHaveBeenCalledWith(false);
});
});