The code cited its plan instead of saying why: `E28 review J4`, `(R6 S3b)`, `S1 justified…`,
`deep-review round 5`. That plan lives in the private ops repo, so for every reader of this one the
citation was noise, and a sentence whose subject was the plan step ("round 2 showed…") hid its
lesson behind an id. Each one is gone and the "why" kept: a bare citation is deleted, a sentence
carrying a lesson is reworded around it ("a later attempt showed…").
Measured (`scripts/audit_metrics.py`, product code): 652 lines in 270 files carried an epic code by
the definition the next commit holds (507 / 241 by the old, two-digit-only one) -> 0. Across all
code, tests, scripts and configs: ~1100 epic-code lines plus ~320 sprint/round ids.
Behaviour unchanged, checked mechanically: every changed .py file has the same AST once docstrings
are blanked; css/sh/toml/yml/json files are identical once comments are stripped; the only
non-comment changes in TS/JS are test titles, one description string in a contract table, and five
ESLint messages, whose text is all the gates snapshot diff holds. Not touched: Markdown (docs and
the changelog keep their history), Alembic migrations, TV episode notation (`S2 · E5`), DESIGN.md
ids (`C1`, `B4`, `S3h`), tracker ids (`SEC-16`, `DX-17`).
One stale claim fixed on the way: test_hls_reaper's docstring said the player checkpoints "every
10 s whether or not it is playing", which plex/stream.py calls wrong; it now says what the code does.
109 lines
4.2 KiB
TypeScript
109 lines
4.2 KiB
TypeScript
// @vitest-environment jsdom
|
|
//
|
|
// NavigationProvider's URL-derived seeds, backfilling a code 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: 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<string, string | null> }));
|
|
vi.mock("../lib/storage", async (importOriginal) => {
|
|
const actual = await importOriginal<typeof import("../lib/storage")>();
|
|
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");
|
|
});
|
|
// 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)", () => {
|
|
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();
|
|
});
|
|
});
|