Files
siftlode/frontend/src/lib/tabState.dom.test.ts
T
peter d4f24de4ba 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.
2026-10-26 01:13:39 +01:00

62 lines
2.7 KiB
TypeScript

// @vitest-environment jsdom
//
// Owner's call: a page's sub-tab was remembered forever in localStorage, so every fresh browser tab
// opened Configuration on "Plex" as if that were its home. The position is now kept per browser tab
// (sessionStorage): it survives a reload and a trip to another page, and a new tab starts on the first.
import { afterEach, beforeEach, describe, expect, it } from "vitest";
import { act, renderHook } from "@testing-library/react";
import { claimLocalData, setTabRaw, useTabPersistedState } from "./storage";
beforeEach(() => {
claimLocalData(1);
});
afterEach(() => {
sessionStorage.clear();
localStorage.clear();
});
describe("a page's sub-tab, per browser tab", () => {
it("starts on the fallback, then keeps the picked tab for this browser tab only", () => {
const first = renderHook(() => useTabPersistedState("siftlode.configTab", "access"));
expect(first.result.current[0]).toBe("access");
act(() => first.result.current[1]("plex"));
expect(sessionStorage.getItem("siftlode.configTab")).toBe("plex");
expect(localStorage.getItem("siftlode.configTab")).toBeNull();
// The page mounts again in this tab (a reload, or back from another page): it is where it was.
first.unmount();
expect(
renderHook(() => useTabPersistedState("siftlode.configTab", "access")).result.current[0],
).toBe("plex");
});
it("ignores a position left in localStorage by an older build, and clears it", () => {
localStorage.setItem("siftlode.configTab", "plex");
const { result } = renderHook(() => useTabPersistedState("siftlode.configTab", "access"));
expect(result.current[0]).toBe("access");
expect(localStorage.getItem("siftlode.configTab")).toBeNull();
});
it("a pre-selected tab is the one the page opens on", () => {
setTabRaw("siftlode.adminUsersTab", "access");
const { result } = renderHook(() => useTabPersistedState("siftlode.adminUsersTab", "roles"));
expect(result.current[0]).toBe("access");
});
it("opens on the tab the address names, and keeps it for this browser tab", () => {
setTabRaw("siftlode.settingsTab", "account");
window.history.replaceState(null, "", "/?page=settings&stab=tokens");
const { result, unmount } = renderHook(() =>
useTabPersistedState("siftlode.settingsTab", "appearance", "stab"),
);
expect(result.current[0]).toBe("tokens");
unmount();
// Back on the page later, through the rail (the page switch cleared its address).
window.history.replaceState(null, "", "/?page=settings");
expect(
renderHook(() => useTabPersistedState("siftlode.settingsTab", "appearance", "stab")).result
.current[0],
).toBe("tokens");
window.history.replaceState(null, "", "/");
});
});