// @vitest-environment jsdom // // NavigationProvider's URL-derived seeds, backfilling the E4 deep-review's deferred coverage: // • loadInitialPage — the bookmark deep-link precedence (?page > ?v > ?pl > filters/?chan > the // account's stored landing page > feed). // • channelViewFrom — the shared _chan/?chan resolver behind BOTH the channelView seed and the // onPop handler (the S1 fix): a popstate landing on a URL-only bookmark entry must restore the // channel from ?chan, not close it. // Only getAccountRaw is stubbed (the account's stored landing page); everything else is real. import { describe, it, expect, beforeEach, vi } from "vitest"; const { stored } = vi.hoisted(() => ({ stored: {} as Record })); vi.mock("../lib/storage", async (importOriginal) => { const actual = await importOriginal(); return { ...actual, getAccountRaw: (k: string) => stored[k] ?? null }; }); import { loadInitialPage, channelViewFrom, START_ON_HOME } from "./navigationInit"; import { LS } from "../lib/storage"; const setUrl = (search: string) => window.history.replaceState(null, "", search || "/"); beforeEach(() => { setUrl("/"); for (const k of Object.keys(stored)) delete stored[k]; }); describe("loadInitialPage precedence", () => { it("?page wins and is validated", () => { setUrl("?page=stats"); expect(loadInitialPage()).toBe("stats"); }); it("an invalid ?page falls back to feed", () => { setUrl("?page=bogus"); expect(loadInitialPage()).toBe("feed"); }); it("?v implies the plex module", () => { setUrl("?v=show:1"); expect(loadInitialPage()).toBe("plex"); }); it("?pl implies playlists", () => { setUrl("?pl=3"); expect(loadInitialPage()).toBe("playlists"); }); it("a filter param implies the feed", () => { setUrl("?tags=1,2"); expect(loadInitialPage()).toBe("feed"); }); it("?chan (the channel overlay) implies the feed", () => { setUrl("?chan=UC1"); expect(loadInitialPage()).toBe("feed"); }); it("?page beats a lower-precedence param", () => { setUrl("?page=stats&v=show:1"); expect(loadInitialPage()).toBe("stats"); }); it("?v beats ?pl and filters", () => { setUrl("?v=show:1&pl=3&tags=1"); expect(loadInitialPage()).toBe("plex"); }); // E24 changed this rung: a bare URL lands on Home, OVER the remembered module. Landing on // whatever you happened to close the app on is precisely the habit the anti-paralysis surface // exists to replace, so the remembered page only wins once the account opts out. it("a bare URL lands on Home even when another module is remembered", () => { stored[LS.page] = "downloads"; expect(loadInitialPage()).toBe("home"); }); it("opting out restores the account's stored landing page", () => { stored[LS.startOnHome] = START_ON_HOME.off; stored[LS.page] = "downloads"; expect(loadInitialPage()).toBe("downloads"); }); it("opted out with no / invalid stored page still defaults to feed", () => { stored[LS.startOnHome] = START_ON_HOME.off; expect(loadInitialPage()).toBe("feed"); stored[LS.page] = "nope"; expect(loadInitialPage()).toBe("feed"); }); it("a deep link still beats Home", () => { setUrl("?pl=3"); expect(loadInitialPage()).toBe("playlists"); }); }); describe("channelViewFrom", () => { it("reads _chan (+ _chanName) from an in-app entry", () => { expect(channelViewFrom({ _chan: "UC1", _chanName: "Chan" }, "")).toEqual({ id: "UC1", name: "Chan", }); }); it("_chan without a name yields an undefined name", () => { expect(channelViewFrom({ _chan: "UC1" }, "")).toEqual({ id: "UC1", name: undefined }); }); it("falls back to the ?chan URL param when the entry has no _chan (fresh bookmark) — the S1 fix", () => { expect(channelViewFrom(null, "?chan=UC9")).toEqual({ id: "UC9", name: undefined }); }); it("prefers _chan over the URL param", () => { expect(channelViewFrom({ _chan: "UCstate" }, "?chan=UCurl")).toEqual({ id: "UCstate", name: undefined, }); }); it("returns null when neither is present (channel closed)", () => { expect(channelViewFrom({}, "")).toBeNull(); expect(channelViewFrom(null, "/")).toBeNull(); }); });