feat(nav): tabs, list views and name searches are named in the address
Settings, Configuration and Users name their tab (stab/cfgtab/utab); a link's tab wins and a tab pre-selected while its page is on screen now switches it. A playlist's sort, filters and grouping (plsort/plf/plgroup), the Files sort (fsort, always written) and the name searches of Channels, Files, Playlists and Plex (cq/fq/plq/pq+pqf) reopen from the address; the searches are written once the typing pauses.
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
// @vitest-environment jsdom
|
||||
//
|
||||
// The URL is the view: Settings' tab is named in the address, so a reload or a bookmark opens the tab
|
||||
// it showed (it lived in sessionStorage alone: a bookmark opened Appearance). And a notice's link to a
|
||||
// tab, followed while Settings is already on screen, turns to it — the navigation to the page it is on
|
||||
// is a no-op, so the pre-selection used to wait for the next visit.
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { act, cleanup, fireEvent, render, screen } from "@testing-library/react";
|
||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||
|
||||
vi.mock("react-i18next", async (importOriginal) => ({
|
||||
...(await importOriginal<typeof import("react-i18next")>()),
|
||||
useTranslation: () => ({ t: (k: string) => k, i18n: { language: "en" } }),
|
||||
}));
|
||||
vi.mock("../../lib/useMe", () => ({ useMe: () => ({ id: 1, email: "a@x", role: "user" }) }));
|
||||
vi.mock("../../features/prefs/prefsContext", () => ({ usePrefs: () => ({}) }));
|
||||
vi.mock("../../features/wizard/wizardContext", () => ({
|
||||
useWizard: () => ({ openWizard: () => {} }),
|
||||
}));
|
||||
// The tabs' own content is not what is under test.
|
||||
vi.mock("./ApiTokens", () => ({ default: () => <p>tokens-tab</p> }));
|
||||
vi.mock("./DiagnosticsSettings", () => ({ default: () => <p>diagnostics-tab</p> }));
|
||||
|
||||
import SettingsPanel from "./SettingsPanel";
|
||||
import { focusSettingsTab } from "../../lib/settingsTab";
|
||||
import { claimLocalData } from "../../lib/storage";
|
||||
|
||||
beforeEach(() => {
|
||||
claimLocalData(1);
|
||||
});
|
||||
afterEach(() => {
|
||||
cleanup();
|
||||
sessionStorage.clear();
|
||||
localStorage.clear();
|
||||
window.history.replaceState(null, "", "/");
|
||||
});
|
||||
|
||||
const search = () => new URLSearchParams(window.location.search);
|
||||
const mount = () =>
|
||||
render(
|
||||
<QueryClientProvider client={new QueryClient()}>
|
||||
<SettingsPanel />
|
||||
</QueryClientProvider>,
|
||||
);
|
||||
|
||||
describe("Settings' tab in the address", () => {
|
||||
it("opens on the tab a link names, over the one this browser tab last showed", () => {
|
||||
focusSettingsTab("diagnostics");
|
||||
window.history.replaceState(null, "", "/?page=settings&stab=tokens");
|
||||
mount();
|
||||
expect(screen.getByText("tokens-tab")).toBeTruthy();
|
||||
expect(search().get("stab")).toBe("tokens");
|
||||
});
|
||||
|
||||
it("names the tab picked", () => {
|
||||
window.history.replaceState(null, "", "/?page=settings&stab=tokens");
|
||||
mount();
|
||||
fireEvent.click(screen.getByTestId("settings-tab-diagnostics"));
|
||||
expect(screen.getByText("diagnostics-tab")).toBeTruthy();
|
||||
expect(search().get("stab")).toBe("diagnostics");
|
||||
});
|
||||
|
||||
it("turns to a tab pre-selected while the page is on screen", () => {
|
||||
window.history.replaceState(null, "", "/?page=settings&stab=tokens");
|
||||
mount();
|
||||
act(() => focusSettingsTab("diagnostics"));
|
||||
expect(screen.getByText("diagnostics-tab")).toBeTruthy();
|
||||
expect(search().get("stab")).toBe("diagnostics");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user