Files
jellytau/src/lib/stores/searchGroupOrder.test.ts
T
dtourolle ad48d89dfe chore(format): run prettier over src/ and scripts/
Formatting was configured but never enforced: `bun run format:check`
reported 199 unformatted files and ran in no workflow and in no git hook,
so .prettierrc (printWidth 100, trailing commas) described an intention
rather than the tree.

This is the one-time sweep that makes the check gateable. Whitespace and
token-reflow only -- no behavioural change: `bun run check` reports 0
errors and all 1053 frontend tests pass before and after.

Kept out of every other commit on purpose. A 199-file diff mixed with
real changes is unreviewable, and the next commit turns format:check
into a hard CI gate so this cannot silently accumulate again.
2026-08-21 17:41:44 +02:00

146 lines
4.3 KiB
TypeScript

/**
* Persisted search result group order.
*
* TRACES: UR-050 | DR-066 | UT-*
*/
import { describe, it, expect, beforeEach, beforeAll, afterAll, vi } from "vitest";
import { get } from "svelte/store";
import { DEFAULT_GROUP_ORDER } from "$lib/utils/searchScope";
const STORAGE_KEY = "jellytau-search-group-order";
// This jsdom setup doesn't expose localStorage, so stand in a minimal
// implementation — the store only uses getItem/setItem.
const store = new Map<string, string>();
const localStorage = {
getItem: (key: string) => store.get(key) ?? null,
setItem: (key: string, value: string) => void store.set(key, value),
removeItem: (key: string) => void store.delete(key),
clear: () => store.clear(),
};
beforeAll(() => {
vi.stubGlobal("localStorage", localStorage);
});
afterAll(() => {
vi.unstubAllGlobals();
});
describe("searchGroupOrder", () => {
beforeEach(() => {
vi.resetModules();
localStorage.clear();
});
it("starts at the shipped default with nothing stored", async () => {
const { searchGroupOrder } = await import("./searchGroupOrder");
expect(get(searchGroupOrder)).toEqual([...DEFAULT_GROUP_ORDER]);
});
it("loads a stored order", async () => {
localStorage.setItem(
STORAGE_KEY,
JSON.stringify(["episodes", "shows", "movies", "songs", "albums", "artists", "people"]),
);
const { searchGroupOrder } = await import("./searchGroupOrder");
expect(get(searchGroupOrder)).toEqual([
"episodes",
"shows",
"movies",
"songs",
"albums",
"artists",
"people",
]);
});
it("migrates a stored `tvShows` from before the group split", async () => {
// Upgrading must keep the user's placement of TV, not append the two new
// groups at the bottom.
localStorage.setItem(STORAGE_KEY, JSON.stringify(["tvShows", "movies"]));
const { searchGroupOrder } = await import("./searchGroupOrder");
expect(get(searchGroupOrder)).toEqual([
"shows",
"episodes",
"movies",
"songs",
"albums",
"artists",
"people",
]);
});
it("appends groups a partial stored order does not mention", async () => {
localStorage.setItem(STORAGE_KEY, JSON.stringify(["movies"]));
const { searchGroupOrder } = await import("./searchGroupOrder");
expect(get(searchGroupOrder)).toEqual([
"movies",
"shows",
"episodes",
"songs",
"albums",
"artists",
"people",
]);
});
it("falls back to the default on corrupt stored JSON", async () => {
localStorage.setItem(STORAGE_KEY, "{not json");
const { searchGroupOrder } = await import("./searchGroupOrder");
expect(get(searchGroupOrder)).toEqual([...DEFAULT_GROUP_ORDER]);
});
it("persists a move so the order survives a restart", async () => {
const { searchGroupOrder } = await import("./searchGroupOrder");
// Default is shows, episodes, movies, songs, … — move movies up one.
searchGroupOrder.move("movies", -1);
const expected = ["shows", "movies", "episodes", "songs", "albums", "artists", "people"];
expect(get(searchGroupOrder)).toEqual(expected);
expect(JSON.parse(localStorage.getItem(STORAGE_KEY)!)).toEqual(expected);
// Simulate a fresh app start reading the same storage.
vi.resetModules();
const reloaded = await import("./searchGroupOrder");
expect(get(reloaded.searchGroupOrder)).toEqual(expected);
});
it("persists a drag reorder", async () => {
const { searchGroupOrder } = await import("./searchGroupOrder");
// Drag "albums" (index 4) to the front.
searchGroupOrder.reorder(4, 0);
expect(get(searchGroupOrder)).toEqual([
"albums",
"shows",
"episodes",
"movies",
"songs",
"artists",
"people",
]);
});
it("resets to the shipped default", async () => {
const { searchGroupOrder } = await import("./searchGroupOrder");
searchGroupOrder.move("movies", -1);
searchGroupOrder.reset();
expect(get(searchGroupOrder)).toEqual([...DEFAULT_GROUP_ORDER]);
});
it("normalizes an explicitly set order", async () => {
const { searchGroupOrder } = await import("./searchGroupOrder");
searchGroupOrder.set(["movies", "podcasts"] as never);
expect(get(searchGroupOrder)).toEqual([
"movies",
"shows",
"episodes",
"songs",
"albums",
"artists",
"people",
]);
});
});