refactor(ui): reuse the store, media-query and deleted-tag rules the review found rebuilt, and name a loading pick
E32 review round 1 (F3–F6). - Channels' open-row store and the chat dock use lib/store's createStore instead of a hand-rolled listener set (the chat dock gets a test of its own). - The Plex backdrop reads prefers-reduced-motion through useMediaQuery; the query string is one constant (REDUCED_MOTION) for the hook and the carousel's one-off read. - A link-restored collection filter showed its raw rating_key in the picker while the titles loaded: usePlexCollectionTitles now says it is pending, the picker draws a placeholder (labelsPending, as the channel picker does) and so does the chip row. - The "deleted tag" rule was written twice with two i18n keys and had drifted: the channel manager showed NO chip for a pick while the tag list loaded, or ever after a failed load, while the pick still narrowed the table. One rule now (lib/tagPicks), one key (common.deletedTag); the manager's row shows every pick, as a placeholder while loading and as its id after a failure.
This commit is contained in:
@@ -44,7 +44,7 @@ describe("usePlexCollectionTitles", () => {
|
||||
wrapper: wrap(),
|
||||
});
|
||||
await waitFor(() =>
|
||||
expect(result.current["17045"]).toBe("Pirates of the Caribbean Collection"),
|
||||
expect(result.current.titles["17045"]).toBe("Pirates of the Caribbean Collection"),
|
||||
);
|
||||
// Only the missing ids are asked for — nothing else.
|
||||
expect(plexCollections).toHaveBeenCalledWith(undefined, undefined, ["17045"]);
|
||||
@@ -55,7 +55,7 @@ describe("usePlexCollectionTitles", () => {
|
||||
const { result } = renderHook(() => usePlexCollectionTitles(["17045"], known), {
|
||||
wrapper: wrap(),
|
||||
});
|
||||
expect(result.current["17045"]).toBe("Pirates of the Caribbean Collection");
|
||||
expect(result.current.titles["17045"]).toBe("Pirates of the Caribbean Collection");
|
||||
// Give a would-be fetch a chance to happen before asserting it did not.
|
||||
await new Promise((r) => setTimeout(r, 20));
|
||||
expect(plexCollections).not.toHaveBeenCalled();
|
||||
@@ -66,10 +66,10 @@ describe("usePlexCollectionTitles", () => {
|
||||
() => usePlexCollectionTitles(["17045", "68231"], { "17045": "Already Known" }),
|
||||
{ wrapper: wrap() },
|
||||
);
|
||||
await waitFor(() => expect(result.current["68231"]).toBe("IMDb Top 250"));
|
||||
await waitFor(() => expect(result.current.titles["68231"]).toBe("IMDb Top 250"));
|
||||
// The known id is not in the request — and its stored title survives the merge.
|
||||
expect(plexCollections).toHaveBeenCalledWith(undefined, undefined, ["68231"]);
|
||||
expect(result.current["17045"]).toBe("Already Known");
|
||||
expect(result.current.titles["17045"]).toBe("Already Known");
|
||||
});
|
||||
|
||||
it("treats the same ids in a different order as one query", async () => {
|
||||
@@ -77,12 +77,12 @@ describe("usePlexCollectionTitles", () => {
|
||||
const a = renderHook(() => usePlexCollectionTitles(["68231", "17045"], undefined), {
|
||||
wrapper: w,
|
||||
});
|
||||
await waitFor(() => expect(a.result.current["17045"]).toBeDefined());
|
||||
await waitFor(() => expect(a.result.current.titles["17045"]).toBeDefined());
|
||||
const calls = plexCollections.mock.calls.length;
|
||||
const b = renderHook(() => usePlexCollectionTitles(["17045", "68231"], undefined), {
|
||||
wrapper: w,
|
||||
});
|
||||
await waitFor(() => expect(b.result.current["17045"]).toBeDefined());
|
||||
await waitFor(() => expect(b.result.current.titles["17045"]).toBeDefined());
|
||||
expect(plexCollections.mock.calls.length).toBe(calls);
|
||||
});
|
||||
|
||||
@@ -91,7 +91,21 @@ describe("usePlexCollectionTitles", () => {
|
||||
const { result } = renderHook(() => usePlexCollectionTitles(["17045"], undefined), {
|
||||
wrapper: wrap(),
|
||||
});
|
||||
// The caller falls back to its own label; it must not be handed a half-built map.
|
||||
expect(result.current["17045"]).toBeUndefined();
|
||||
// The caller falls back to its own label; it must not be handed a half-built map — and it is
|
||||
// told the names are on their way, so it draws a placeholder rather than the raw id.
|
||||
expect(result.current.titles["17045"]).toBeUndefined();
|
||||
expect(result.current.pending).toBe(true);
|
||||
});
|
||||
|
||||
it("is not pending when nothing is missing, nor once the lookup answered", async () => {
|
||||
const known = renderHook(() => usePlexCollectionTitles(["17045"], { "17045": "Known" }), {
|
||||
wrapper: wrap(),
|
||||
});
|
||||
expect(known.result.current.pending).toBe(false);
|
||||
const cold = renderHook(() => usePlexCollectionTitles(["17045"], undefined), {
|
||||
wrapper: wrap(),
|
||||
});
|
||||
await waitFor(() => expect(cold.result.current.pending).toBe(false));
|
||||
expect(cold.result.current.titles["17045"]).toBe("Pirates of the Caribbean Collection");
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user