Spaces:
Running
Running
File size: 4,231 Bytes
abf1288 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | 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);
});
});
|