Files
jellytau/src/lib/components/library/libraryMosaic.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

103 lines
3.5 KiB
TypeScript

import { describe, it, expect } from "vitest";
import type { Library } from "$lib/api/types";
import { buildLibraryMosaic, assumedLibraryRatio } from "./libraryMosaic";
function lib(
id: string,
name: string,
collectionType: string,
favoritesScope?: Library["favoritesScope"],
): Library {
return { id, name, collectionType, favoritesScope } as Library;
}
const MOVIES = lib("1", "Movies", "movies", "movies");
const SHOWS = lib("2", "Shows", "tvshows", "tv");
const MUSIC = lib("3", "Music", "music", "music");
const LIVETV = lib("4", "Live TV", "livetv");
describe("buildLibraryMosaic", () => {
it("leads with the cross-library favourites entry", () => {
const entries = buildLibraryMosaic([MOVIES]);
expect(entries[0]).toMatchObject({
kind: "favorites",
scope: "all",
label: "Favourites",
href: "/library/favorites",
});
});
it("puts each library's own favourites tile right after it", () => {
const entries = buildLibraryMosaic([MOVIES, MUSIC]);
expect(entries.map((e) => e.label)).toEqual([
"Favourites",
"Movies",
"Favourite Movies",
"Music",
"Favourite Music",
]);
});
it("links a category tile to that category's favourites tab", () => {
const entries = buildLibraryMosaic([SHOWS]);
const tile = entries.find((e) => e.label === "Favourite Shows");
expect(tile).toMatchObject({
kind: "favorites",
scope: "tv",
href: "/library/favorites?scope=tv",
});
});
it("offers a category's favourites once, however many libraries share it", () => {
const entries = buildLibraryMosaic([MOVIES, lib("5", "Kids Films", "movies", "movies")]);
expect(entries.filter((e) => e.kind === "favorites" && e.scope === "movies")).toHaveLength(1);
expect(entries.map((e) => e.label)).toEqual([
"Favourites",
"Movies",
"Favourite Movies",
"Kids Films",
]);
});
it("gives no favourites tile to a library kind favourites do not carve up", () => {
const entries = buildLibraryMosaic([LIVETV]);
expect(entries.map((e) => e.label)).toEqual(["Favourites", "Live TV"]);
});
it("ignores a scope the favourites page does not offer as a tab", () => {
const odd = lib("6", "Books", "books", "books" as Library["favoritesScope"]);
const entries = buildLibraryMosaic([odd]);
expect(entries.map((e) => e.label)).toEqual(["Favourites", "Books"]);
});
it("keeps every library, and keys tiles uniquely", () => {
const entries = buildLibraryMosaic([MOVIES, SHOWS, MUSIC, LIVETV]);
expect(entries.filter((e) => e.kind === "library")).toHaveLength(4);
expect(new Set(entries.map((e) => e.key)).size).toBe(entries.length);
});
it("has nothing but the favourites entry when there are no libraries", () => {
expect(buildLibraryMosaic([]).map((e) => e.key)).toEqual(["favorites:all"]);
});
it("gives a category tile the shape of the library it follows", () => {
const entries = buildLibraryMosaic([MUSIC, MOVIES]);
const musicFavorites = entries.find((e) => e.label === "Favourite Music")!;
const movieFavorites = entries.find((e) => e.label === "Favourite Movies")!;
expect(musicFavorites.ratio).toBe(assumedLibraryRatio(MUSIC));
expect(movieFavorites.ratio).toBe(assumedLibraryRatio(MOVIES));
});
});
describe("assumedLibraryRatio", () => {
it("assumes a square cover for music and a wide backdrop otherwise", () => {
expect(assumedLibraryRatio(MUSIC)).toBe(1);
expect(assumedLibraryRatio(MOVIES)).toBeCloseTo(16 / 9);
expect(assumedLibraryRatio(LIVETV)).toBeCloseTo(16 / 9);
});
});