mirror of
https://github.com/wkulhanek/bonob.git
synced 2025-12-21 17:33:29 +01:00
Genre with id and name, rather than just name
This commit is contained in:
@@ -49,18 +49,23 @@ export type AlbumSummary = {
|
||||
id: string;
|
||||
name: string;
|
||||
year: string | undefined;
|
||||
genre: string | undefined;
|
||||
genre: Genre | undefined;
|
||||
};
|
||||
|
||||
export type Album = AlbumSummary & {};
|
||||
|
||||
export type Genre = {
|
||||
name: string;
|
||||
id: string;
|
||||
}
|
||||
|
||||
export type Track = {
|
||||
id: string;
|
||||
name: string;
|
||||
mimeType: string;
|
||||
duration: number;
|
||||
number: number | undefined;
|
||||
genre: string | undefined;
|
||||
genre: Genre | undefined;
|
||||
album: AlbumSummary;
|
||||
artist: ArtistSummary;
|
||||
};
|
||||
@@ -137,7 +142,7 @@ export interface MusicLibrary {
|
||||
album(id: string): Promise<Album>;
|
||||
tracks(albumId: string): Promise<Track[]>;
|
||||
track(trackId: string): Promise<Track>;
|
||||
genres(): Promise<string[]>;
|
||||
genres(): Promise<Genre[]>;
|
||||
stream({
|
||||
trackId,
|
||||
range,
|
||||
|
||||
@@ -17,6 +17,7 @@ import {
|
||||
Images,
|
||||
AlbumSummary,
|
||||
NO_IMAGES,
|
||||
Genre,
|
||||
} from "./music_service";
|
||||
import X2JS from "x2js";
|
||||
import sharp from "sharp";
|
||||
@@ -193,7 +194,7 @@ const asTrack = (album: Album, song: song) => ({
|
||||
mimeType: song._contentType,
|
||||
duration: parseInt(song._duration || "0"),
|
||||
number: parseInt(song._track || "0"),
|
||||
genre: song._genre,
|
||||
genre: maybeAsGenre(song._genre),
|
||||
album,
|
||||
artist: {
|
||||
id: song._artistId,
|
||||
@@ -206,9 +207,18 @@ const asAlbum = (album: album) => ({
|
||||
id: album._id,
|
||||
name: album._name,
|
||||
year: album._year,
|
||||
genre: album._genre,
|
||||
genre: maybeAsGenre(album._genre),
|
||||
});
|
||||
|
||||
export const asGenre = (genreName: string) => ({ id: genreName, name: genreName });
|
||||
|
||||
const maybeAsGenre = (genreName: string | undefined): Genre | undefined =>
|
||||
pipe(
|
||||
O.fromNullable(genreName),
|
||||
O.map(asGenre),
|
||||
O.getOrElseW(() => undefined)
|
||||
);
|
||||
|
||||
export class Navidrome implements MusicService {
|
||||
url: string;
|
||||
encryption: Encryption;
|
||||
@@ -318,7 +328,7 @@ export class Navidrome implements MusicService {
|
||||
id: album._id,
|
||||
name: album._name,
|
||||
year: album._year,
|
||||
genre: album._genre,
|
||||
genre: maybeAsGenre(album._genre),
|
||||
}));
|
||||
|
||||
getArtist = (
|
||||
@@ -336,7 +346,7 @@ export class Navidrome implements MusicService {
|
||||
id: album._id,
|
||||
name: album._name,
|
||||
year: album._year,
|
||||
genre: album._genre,
|
||||
genre: maybeAsGenre(album._genre),
|
||||
})),
|
||||
}));
|
||||
|
||||
@@ -399,7 +409,7 @@ export class Navidrome implements MusicService {
|
||||
id: album._id,
|
||||
name: album._name,
|
||||
year: album._year,
|
||||
genre: album._genre,
|
||||
genre: maybeAsGenre(album._genre),
|
||||
}))
|
||||
)
|
||||
.then(slice2(q))
|
||||
@@ -416,7 +426,8 @@ export class Navidrome implements MusicService {
|
||||
pipe(
|
||||
it.genres.genre,
|
||||
A.map((it) => it.__text),
|
||||
A.sort(ordString)
|
||||
A.sort(ordString),
|
||||
A.map((it) => ({ id: it, name: it }))
|
||||
)
|
||||
),
|
||||
tracks: (albumId: string) =>
|
||||
|
||||
11
src/smapi.ts
11
src/smapi.ts
@@ -10,6 +10,7 @@ import {
|
||||
Album,
|
||||
AlbumSummary,
|
||||
ArtistSummary,
|
||||
Genre,
|
||||
MusicLibrary,
|
||||
MusicService,
|
||||
slice2,
|
||||
@@ -184,10 +185,10 @@ const container = ({
|
||||
title,
|
||||
});
|
||||
|
||||
const genre = (genre: string) => ({
|
||||
const genre = (genre: Genre) => ({
|
||||
itemType: "container",
|
||||
id: `genre:${genre}`,
|
||||
title: genre,
|
||||
id: `genre:${genre.id}`,
|
||||
title: genre.name,
|
||||
});
|
||||
|
||||
export const defaultAlbumArtURI = (
|
||||
@@ -235,8 +236,8 @@ export const track = (
|
||||
artist: track.artist.name,
|
||||
artistId: track.artist.id,
|
||||
duration: track.duration,
|
||||
genre: track.album.genre,
|
||||
// genreId
|
||||
genre: track.album.genre?.name,
|
||||
genreId: track.album.genre?.id,
|
||||
trackNumber: track.number,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -80,15 +80,26 @@ export function anArtist(fields: Partial<Artist> = {}): Artist {
|
||||
large: `/artist/art/${id}/large`,
|
||||
},
|
||||
similarArtists: [
|
||||
{ id: uuid(), name: "Similar artist1"},
|
||||
{ id: uuid(), name: "Similar artist2"},
|
||||
{ id: uuid(), name: "Similar artist1" },
|
||||
{ id: uuid(), name: "Similar artist2" },
|
||||
],
|
||||
...fields,
|
||||
};
|
||||
}
|
||||
|
||||
export const SAMPLE_GENRES = ["Metal", "Pop", "Rock", "Hip-Hop"]
|
||||
export const randomGenre = () => SAMPLE_GENRES[randomInt(SAMPLE_GENRES.length)]
|
||||
export const HIP_HOP = { id: "genre_hip_hop", name: "Hip-Hop" };
|
||||
export const METAL = { id: "genre_metal", name: "Metal" };
|
||||
export const NEW_WAVE = { id: "genre_new_wave", name: "New Wave" };
|
||||
export const POP = { id: "genre_pop", name: "Pop" };
|
||||
export const POP_ROCK = { id: "genre_pop_rock", name: "Pop Rock" };
|
||||
export const REGGAE = { id: "genre_reggae", name: "Reggae" };
|
||||
export const ROCK = { id: "genre_rock", name: "Rock" };
|
||||
export const SKA = { id: "genre_ska", name: "Ska" };
|
||||
export const PUNK = { id: "genre_punk", name: "Punk" };
|
||||
export const TRIP_HOP = { id: "genre_trip_hop", name: "Trip Hop" };
|
||||
|
||||
export const SAMPLE_GENRES = [HIP_HOP, METAL, NEW_WAVE, POP, POP_ROCK, REGGAE, ROCK, SKA];
|
||||
export const randomGenre = () => SAMPLE_GENRES[randomInt(SAMPLE_GENRES.length)];
|
||||
|
||||
export function aTrack(fields: Partial<Track> = {}): Track {
|
||||
const id = uuid();
|
||||
@@ -101,8 +112,8 @@ export function aTrack(fields: Partial<Track> = {}): Track {
|
||||
genre: randomGenre(),
|
||||
artist: anArtist(),
|
||||
album: anAlbum(),
|
||||
...fields
|
||||
}
|
||||
...fields,
|
||||
};
|
||||
}
|
||||
|
||||
export function anAlbum(fields: Partial<Album> = {}): Album {
|
||||
@@ -124,13 +135,13 @@ export const BLONDIE: Artist = {
|
||||
id: uuid(),
|
||||
name: "Blondie",
|
||||
year: "1976",
|
||||
genre: "New Wave",
|
||||
genre: NEW_WAVE,
|
||||
},
|
||||
{
|
||||
id: uuid(),
|
||||
name: "Parallel Lines",
|
||||
year: "1978",
|
||||
genre: "Pop Rock",
|
||||
genre: POP_ROCK,
|
||||
},
|
||||
],
|
||||
image: {
|
||||
@@ -138,23 +149,23 @@ export const BLONDIE: Artist = {
|
||||
medium: undefined,
|
||||
large: undefined,
|
||||
},
|
||||
similarArtists: []
|
||||
similarArtists: [],
|
||||
};
|
||||
|
||||
export const BOB_MARLEY: Artist = {
|
||||
id: uuid(),
|
||||
name: "Bob Marley",
|
||||
albums: [
|
||||
{ id: uuid(), name: "Burin'", year: "1973", genre: "Reggae", },
|
||||
{ id: uuid(), name: "Exodus", year: "1977", genre: "Reggae", },
|
||||
{ id: uuid(), name: "Kaya", year: "1978", genre: "Ska", },
|
||||
{ id: uuid(), name: "Burin'", year: "1973", genre: REGGAE },
|
||||
{ id: uuid(), name: "Exodus", year: "1977", genre: REGGAE },
|
||||
{ id: uuid(), name: "Kaya", year: "1978", genre: SKA },
|
||||
],
|
||||
image: {
|
||||
small: "http://localhost/BOB_MARLEY/sml",
|
||||
medium: "http://localhost/BOB_MARLEY/med",
|
||||
large: "http://localhost/BOB_MARLEY/lge",
|
||||
},
|
||||
similarArtists: []
|
||||
similarArtists: [],
|
||||
};
|
||||
|
||||
export const MADONNA: Artist = {
|
||||
@@ -166,7 +177,7 @@ export const MADONNA: Artist = {
|
||||
medium: undefined,
|
||||
large: "http://localhost/MADONNA/lge",
|
||||
},
|
||||
similarArtists: []
|
||||
similarArtists: [],
|
||||
};
|
||||
|
||||
export const METALLICA: Artist = {
|
||||
@@ -177,13 +188,13 @@ export const METALLICA: Artist = {
|
||||
id: uuid(),
|
||||
name: "Ride the Lightening",
|
||||
year: "1984",
|
||||
genre: "Heavy Metal",
|
||||
genre: METAL,
|
||||
},
|
||||
{
|
||||
id: uuid(),
|
||||
name: "Master of Puppets",
|
||||
year: "1986",
|
||||
genre: "Heavy Metal",
|
||||
genre: METAL,
|
||||
},
|
||||
],
|
||||
image: {
|
||||
@@ -191,7 +202,7 @@ export const METALLICA: Artist = {
|
||||
medium: "http://localhost/METALLICA/med",
|
||||
large: "http://localhost/METALLICA/lge",
|
||||
},
|
||||
similarArtists: []
|
||||
similarArtists: [],
|
||||
};
|
||||
|
||||
export const ALL_ARTISTS = [BOB_MARLEY, BLONDIE, MADONNA, METALLICA];
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
albumToAlbumSummary,
|
||||
} from "../src/music_service";
|
||||
import { v4 as uuid } from "uuid";
|
||||
import { anArtist, anAlbum, aTrack } from "./builders";
|
||||
import { anArtist, anAlbum, aTrack, POP, ROCK, METAL, HIP_HOP, SKA } from "./builders";
|
||||
|
||||
describe("InMemoryMusicService", () => {
|
||||
const service = new InMemoryMusicService();
|
||||
@@ -190,16 +190,16 @@ describe("InMemoryMusicService", () => {
|
||||
});
|
||||
|
||||
describe("albums", () => {
|
||||
const artist1_album1 = anAlbum({ genre: "Pop" });
|
||||
const artist1_album2 = anAlbum({ genre: "Rock" });
|
||||
const artist1_album3 = anAlbum({ genre: "Metal" });
|
||||
const artist1_album4 = anAlbum({ genre: "Pop" });
|
||||
const artist1_album5 = anAlbum({ genre: "Pop" });
|
||||
const artist1_album1 = anAlbum({ genre: POP });
|
||||
const artist1_album2 = anAlbum({ genre: ROCK });
|
||||
const artist1_album3 = anAlbum({ genre: METAL });
|
||||
const artist1_album4 = anAlbum({ genre: POP });
|
||||
const artist1_album5 = anAlbum({ genre: POP });
|
||||
|
||||
const artist2_album1 = anAlbum({ genre: "Metal" });
|
||||
const artist2_album1 = anAlbum({ genre: METAL });
|
||||
|
||||
const artist3_album1 = anAlbum({ genre: "Hip-Hop" });
|
||||
const artist3_album2 = anAlbum({ genre: "Pop" });
|
||||
const artist3_album1 = anAlbum({ genre: HIP_HOP });
|
||||
const artist3_album2 = anAlbum({ genre: POP });
|
||||
|
||||
const totalAlbumCount = 8;
|
||||
|
||||
@@ -279,7 +279,7 @@ describe("InMemoryMusicService", () => {
|
||||
it("should return all the albums of that genre for all the artists", async () => {
|
||||
expect(
|
||||
await musicLibrary.albums({
|
||||
genre: "Pop",
|
||||
genre: POP.id,
|
||||
_index: 0,
|
||||
_count: 100,
|
||||
})
|
||||
@@ -300,7 +300,7 @@ describe("InMemoryMusicService", () => {
|
||||
it("should return only the albums for that page", async () => {
|
||||
expect(
|
||||
await musicLibrary.albums({
|
||||
genre: "Pop",
|
||||
genre: POP.id,
|
||||
_index: 1,
|
||||
_count: 2,
|
||||
})
|
||||
@@ -318,7 +318,7 @@ describe("InMemoryMusicService", () => {
|
||||
it("should return only the albums for the last page", async () => {
|
||||
expect(
|
||||
await musicLibrary.albums({
|
||||
genre: "Pop",
|
||||
genre: POP.id,
|
||||
_index: 3,
|
||||
_count: 100,
|
||||
})
|
||||
@@ -367,16 +367,16 @@ describe("InMemoryMusicService", () => {
|
||||
describe("genres", () => {
|
||||
const artist1 = anArtist({
|
||||
albums: [
|
||||
anAlbum({ genre: "Pop" }),
|
||||
anAlbum({ genre: "Rock" }),
|
||||
anAlbum({ genre: "Pop" }),
|
||||
anAlbum({ genre: POP }),
|
||||
anAlbum({ genre: ROCK }),
|
||||
anAlbum({ genre: POP }),
|
||||
],
|
||||
});
|
||||
const artist2 = anArtist({
|
||||
albums: [
|
||||
anAlbum({ genre: "Hip-Hop" }),
|
||||
anAlbum({ genre: "Rap" }),
|
||||
anAlbum({ genre: "Pop" }),
|
||||
anAlbum({ genre: HIP_HOP }),
|
||||
anAlbum({ genre: SKA }),
|
||||
anAlbum({ genre: POP }),
|
||||
],
|
||||
});
|
||||
|
||||
@@ -387,10 +387,10 @@ describe("InMemoryMusicService", () => {
|
||||
describe("fetching all in one page", () => {
|
||||
it("should provide an array of artists", async () => {
|
||||
expect(await musicLibrary.genres()).toEqual([
|
||||
"Hip-Hop",
|
||||
"Pop",
|
||||
"Rap",
|
||||
"Rock",
|
||||
HIP_HOP,
|
||||
POP,
|
||||
ROCK,
|
||||
SKA,
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { option as O } from "fp-ts";
|
||||
import * as A from "fp-ts/Array";
|
||||
import { eqString } from "fp-ts/lib/Eq";
|
||||
import { fromEquals } from "fp-ts/lib/Eq";
|
||||
import { pipe } from "fp-ts/lib/function";
|
||||
import { ordString } from "fp-ts/lib/Ord";
|
||||
import { ordString, fromCompare } from "fp-ts/lib/Ord";
|
||||
|
||||
import {
|
||||
MusicService,
|
||||
@@ -19,13 +19,14 @@ import {
|
||||
albumToAlbumSummary,
|
||||
Album,
|
||||
Track,
|
||||
Genre,
|
||||
} from "../src/music_service";
|
||||
|
||||
type P<T> = (t: T) => boolean;
|
||||
const all: P<any> = (_: any) => true;
|
||||
|
||||
const albumWithGenre = (genre: string): P<[Artist, Album]> => ([_, album]) =>
|
||||
album.genre === genre;
|
||||
const albumWithGenre = (genreId: string): P<[Artist, Album]> => ([_, album]) =>
|
||||
album.genre?.id === genreId;
|
||||
|
||||
export class InMemoryMusicService implements MusicService {
|
||||
users: Record<string, string> = {};
|
||||
@@ -103,8 +104,10 @@ export class InMemoryMusicService implements MusicService {
|
||||
A.flatten,
|
||||
A.map((it) => O.fromNullable(it.genre)),
|
||||
A.compact,
|
||||
A.uniq(eqString),
|
||||
A.sort(ordString)
|
||||
A.uniq(fromEquals((x, y) => x.id === y.id)),
|
||||
A.sort(
|
||||
fromCompare<Genre>((x, y) => ordString.compare(x.id, y.id))
|
||||
)
|
||||
)
|
||||
),
|
||||
tracks: (albumId: string) =>
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
t,
|
||||
BROWSER_HEADERS,
|
||||
DODGY_IMAGE_NAME,
|
||||
asGenre
|
||||
} from "../src/navidrome";
|
||||
import encryption from "../src/encryption";
|
||||
|
||||
@@ -93,7 +94,7 @@ const albumXml = (
|
||||
isDir="true"
|
||||
title="${album.name}" name="${album.name}" album="${album.name}"
|
||||
artist="${artist.name}"
|
||||
genre="${album.genre}"
|
||||
genre="${album.genre?.name}"
|
||||
coverArt="foo"
|
||||
duration="123"
|
||||
playCount="4"
|
||||
@@ -110,7 +111,7 @@ const songXml = (track: Track) => `<song
|
||||
album="${track.album.name}"
|
||||
artist="${track.artist.name}"
|
||||
track="${track.number}"
|
||||
genre="${track.genre}"
|
||||
genre="${track.genre?.name}"
|
||||
isDir="false"
|
||||
coverArt="71381"
|
||||
created="2004-11-08T23:36:11"
|
||||
@@ -251,7 +252,8 @@ describe("Navidrome", () => {
|
||||
|
||||
describe("getting genres", () => {
|
||||
describe("when there is only 1", () => {
|
||||
const genres = ["HipHop"];
|
||||
const genres = ["genre1"];
|
||||
|
||||
beforeEach(() => {
|
||||
mockGET
|
||||
.mockImplementationOnce(() => Promise.resolve(ok(PING_OK)))
|
||||
@@ -265,7 +267,7 @@ describe("Navidrome", () => {
|
||||
.then((it) => navidrome.login(it.authToken))
|
||||
.then((it) => it.genres());
|
||||
|
||||
expect(result).toEqual(genres.sort());
|
||||
expect(result).toEqual(genres.map(asGenre));
|
||||
|
||||
expect(axios.get).toHaveBeenCalledWith(`${url}/rest/getGenres`, {
|
||||
params: {
|
||||
@@ -277,7 +279,7 @@ describe("Navidrome", () => {
|
||||
});
|
||||
|
||||
describe("when there are many", () => {
|
||||
const genres = ["HipHop", "Rap", "TripHop", "Pop", "Rock"];
|
||||
const genres = ["g1", "g2", "g3", "g3"]
|
||||
beforeEach(() => {
|
||||
mockGET
|
||||
.mockImplementationOnce(() => Promise.resolve(ok(PING_OK)))
|
||||
@@ -291,7 +293,7 @@ describe("Navidrome", () => {
|
||||
.then((it) => navidrome.login(it.authToken))
|
||||
.then((it) => it.genres());
|
||||
|
||||
expect(result).toEqual(genres.sort());
|
||||
expect(result).toEqual(genres.map(asGenre));
|
||||
|
||||
expect(axios.get).toHaveBeenCalledWith(`${url}/rest/getGenres`, {
|
||||
params: {
|
||||
@@ -306,9 +308,9 @@ describe("Navidrome", () => {
|
||||
describe("getting an artist", () => {
|
||||
describe("when the artist exists", () => {
|
||||
describe("and has many similar artists", () => {
|
||||
const album1: Album = anAlbum();
|
||||
const album1: Album = anAlbum({ genre: asGenre("Pop") });
|
||||
|
||||
const album2: Album = anAlbum();
|
||||
const album2: Album = anAlbum({ genre: asGenre("Pop") });
|
||||
|
||||
const artist: Artist = anArtist({
|
||||
albums: [album1, album2],
|
||||
@@ -372,9 +374,9 @@ describe("Navidrome", () => {
|
||||
});
|
||||
|
||||
describe("and has one similar artists", () => {
|
||||
const album1: Album = anAlbum();
|
||||
const album1: Album = anAlbum({ genre: asGenre("G1") });
|
||||
|
||||
const album2: Album = anAlbum();
|
||||
const album2: Album = anAlbum({ genre: asGenre("G2") });
|
||||
|
||||
const artist: Artist = anArtist({
|
||||
albums: [album1, album2],
|
||||
@@ -435,9 +437,9 @@ describe("Navidrome", () => {
|
||||
});
|
||||
|
||||
describe("and has no similar artists", () => {
|
||||
const album1: Album = anAlbum();
|
||||
const album1: Album = anAlbum({ genre: asGenre("Jock") });
|
||||
|
||||
const album2: Album = anAlbum();
|
||||
const album2: Album = anAlbum({ genre: asGenre("Mock") });
|
||||
|
||||
const artist: Artist = anArtist({
|
||||
albums: [album1, album2],
|
||||
@@ -498,9 +500,9 @@ describe("Navidrome", () => {
|
||||
});
|
||||
|
||||
describe("and has dodgy looking artist image uris", () => {
|
||||
const album1: Album = anAlbum();
|
||||
const album1: Album = anAlbum({ genre: asGenre("Pop") });
|
||||
|
||||
const album2: Album = anAlbum();
|
||||
const album2: Album = anAlbum({ genre: asGenre("Flop") });
|
||||
|
||||
const artist: Artist = anArtist({
|
||||
albums: [album1, album2],
|
||||
@@ -561,9 +563,9 @@ describe("Navidrome", () => {
|
||||
});
|
||||
|
||||
describe("and has multiple albums", () => {
|
||||
const album1: Album = anAlbum();
|
||||
const album1: Album = anAlbum({ genre: asGenre("Pop") });
|
||||
|
||||
const album2: Album = anAlbum();
|
||||
const album2: Album = anAlbum({ genre: asGenre("Flop") });
|
||||
|
||||
const artist: Artist = anArtist({
|
||||
albums: [album1, album2],
|
||||
@@ -615,7 +617,7 @@ describe("Navidrome", () => {
|
||||
});
|
||||
|
||||
describe("and has only 1 album", () => {
|
||||
const album: Album = anAlbum();
|
||||
const album: Album = anAlbum({ genre: asGenre("Pop") });
|
||||
|
||||
const artist: Artist = anArtist({
|
||||
albums: [album],
|
||||
@@ -842,9 +844,9 @@ describe("Navidrome", () => {
|
||||
|
||||
describe("getting albums", () => {
|
||||
describe("filtering", () => {
|
||||
const album1 = anAlbum({ genre: "Pop" });
|
||||
const album2 = anAlbum({ genre: "Rock" });
|
||||
const album3 = anAlbum({ genre: "Pop" });
|
||||
const album1 = anAlbum({ genre: asGenre("Pop") });
|
||||
const album2 = anAlbum({ genre: asGenre("Rock") });
|
||||
const album3 = anAlbum({ genre: asGenre("Pop") });
|
||||
|
||||
const artist = anArtist({ albums: [album1, album2, album3] });
|
||||
|
||||
@@ -894,7 +896,7 @@ describe("Navidrome", () => {
|
||||
describe("when the artist has only 1 album", () => {
|
||||
const artist1 = anArtist({
|
||||
name: "one hit wonder",
|
||||
albums: [anAlbum()],
|
||||
albums: [anAlbum({ genre: asGenre("Pop") })],
|
||||
});
|
||||
const artists = [artist1];
|
||||
const albums = artists.flatMap((artist) => artist.albums);
|
||||
@@ -974,13 +976,17 @@ describe("Navidrome", () => {
|
||||
});
|
||||
|
||||
describe("when there are less than 500 albums", () => {
|
||||
const genre1 = asGenre("genre1");
|
||||
const genre2 = asGenre("genre2");
|
||||
const genre3 = asGenre("genre3");
|
||||
|
||||
const artist1 = anArtist({
|
||||
name: "abba",
|
||||
albums: [anAlbum(), anAlbum(), anAlbum()],
|
||||
albums: [anAlbum({ genre: genre1 }), anAlbum({ genre: genre2 }), anAlbum({ genre: genre3 })],
|
||||
});
|
||||
const artist2 = anArtist({
|
||||
name: "babba",
|
||||
albums: [anAlbum(), anAlbum(), anAlbum()],
|
||||
albums: [anAlbum({ genre: genre1 }), anAlbum({ genre: genre2 }), anAlbum({ genre: genre3 })],
|
||||
});
|
||||
const artists = [artist1, artist2];
|
||||
const albums = artists.flatMap((artist) => artist.albums);
|
||||
@@ -1048,7 +1054,7 @@ describe("Navidrome", () => {
|
||||
|
||||
describe("when there are more than 500 albums", () => {
|
||||
const first500Albums = range(500).map((i) =>
|
||||
anAlbum({ name: `album ${i}` })
|
||||
anAlbum({ name: `album ${i}`, genre: asGenre(`genre ${i}`) })
|
||||
);
|
||||
const artist = anArtist({
|
||||
name: "> 500 albums",
|
||||
@@ -1101,15 +1107,17 @@ describe("Navidrome", () => {
|
||||
|
||||
describe("getting an album", () => {
|
||||
describe("when it exists", () => {
|
||||
const album = anAlbum();
|
||||
const genre = asGenre("Pop");
|
||||
|
||||
const album = anAlbum({ genre });
|
||||
|
||||
const artist = anArtist({ albums: [album] });
|
||||
|
||||
const tracks = [
|
||||
aTrack({ artist, album }),
|
||||
aTrack({ artist, album }),
|
||||
aTrack({ artist, album }),
|
||||
aTrack({ artist, album }),
|
||||
aTrack({ artist, album, genre }),
|
||||
aTrack({ artist, album, genre }),
|
||||
aTrack({ artist, album, genre }),
|
||||
aTrack({ artist, album, genre }),
|
||||
];
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -1143,7 +1151,10 @@ describe("Navidrome", () => {
|
||||
describe("getting tracks", () => {
|
||||
describe("for an album", () => {
|
||||
describe("when the album has multiple tracks", () => {
|
||||
const album = anAlbum({ id: "album1", name: "Burnin" });
|
||||
const hipHop = asGenre("Hip-Hop")
|
||||
const tripHop = asGenre("Trip-Hop")
|
||||
|
||||
const album = anAlbum({ id: "album1", name: "Burnin", genre: hipHop });
|
||||
const albumSummary = albumToAlbumSummary(album);
|
||||
|
||||
const artist = anArtist({
|
||||
@@ -1157,10 +1168,10 @@ describe("Navidrome", () => {
|
||||
};
|
||||
|
||||
const tracks = [
|
||||
aTrack({ artist: artistSummary, album: albumSummary }),
|
||||
aTrack({ artist: artistSummary, album: albumSummary }),
|
||||
aTrack({ artist: artistSummary, album: albumSummary }),
|
||||
aTrack({ artist: artistSummary, album: albumSummary }),
|
||||
aTrack({ artist: artistSummary, album: albumSummary, genre: hipHop }),
|
||||
aTrack({ artist: artistSummary, album: albumSummary, genre: hipHop }),
|
||||
aTrack({ artist: artistSummary, album: albumSummary, genre: tripHop }),
|
||||
aTrack({ artist: artistSummary, album: albumSummary, genre: tripHop }),
|
||||
];
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -1191,7 +1202,9 @@ describe("Navidrome", () => {
|
||||
});
|
||||
|
||||
describe("when the album has only 1 track", () => {
|
||||
const album = anAlbum({ id: "album1", name: "Burnin" });
|
||||
const flipFlop = asGenre("Flip-Flop")
|
||||
|
||||
const album = anAlbum({ id: "album1", name: "Burnin", genre: flipFlop });
|
||||
const albumSummary = albumToAlbumSummary(album);
|
||||
|
||||
const artist = anArtist({
|
||||
@@ -1204,7 +1217,7 @@ describe("Navidrome", () => {
|
||||
image: NO_IMAGES,
|
||||
};
|
||||
|
||||
const tracks = [aTrack({ artist: artistSummary, album: albumSummary })];
|
||||
const tracks = [aTrack({ artist: artistSummary, album: albumSummary, genre: flipFlop })];
|
||||
|
||||
beforeEach(() => {
|
||||
mockGET
|
||||
@@ -1252,14 +1265,14 @@ describe("Navidrome", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("should return the album", async () => {
|
||||
it("should empty array", async () => {
|
||||
const result = await navidrome
|
||||
.generateToken({ username, password })
|
||||
.then((it) => it as AuthSuccess)
|
||||
.then((it) => navidrome.login(it.authToken))
|
||||
.then((it) => it.tracks(album.id));
|
||||
|
||||
expect(result).toEqual(tracks);
|
||||
expect(result).toEqual([]);
|
||||
|
||||
expect(axios.get).toHaveBeenCalledWith(`${url}/rest/getAlbum`, {
|
||||
params: {
|
||||
@@ -1273,7 +1286,9 @@ describe("Navidrome", () => {
|
||||
});
|
||||
|
||||
describe("a single track", () => {
|
||||
const album = anAlbum({ id: "album1", name: "Burnin" });
|
||||
const pop = asGenre("Pop")
|
||||
|
||||
const album = anAlbum({ id: "album1", name: "Burnin", genre: pop });
|
||||
const albumSummary = albumToAlbumSummary(album);
|
||||
|
||||
const artist = anArtist({
|
||||
@@ -1286,7 +1301,7 @@ describe("Navidrome", () => {
|
||||
image: NO_IMAGES,
|
||||
};
|
||||
|
||||
const track = aTrack({ artist: artistSummary, album: albumSummary });
|
||||
const track = aTrack({ artist: artistSummary, album: albumSummary, genre: pop });
|
||||
|
||||
beforeEach(() => {
|
||||
mockGET
|
||||
|
||||
@@ -29,6 +29,9 @@ import {
|
||||
anArtist,
|
||||
anAlbum,
|
||||
aTrack,
|
||||
POP,
|
||||
ROCK,
|
||||
PUNK, TRIP_HOP
|
||||
} from "./builders";
|
||||
import { InMemoryMusicService } from "./in_memory_music_service";
|
||||
import supersoap from "./supersoap";
|
||||
@@ -187,7 +190,11 @@ describe("track", () => {
|
||||
name: "great song",
|
||||
duration: randomInt(1000),
|
||||
number: randomInt(100),
|
||||
album: anAlbum({ name: "great album", id: uuid(), genre: "some genre" }),
|
||||
album: anAlbum({
|
||||
name: "great album",
|
||||
id: uuid(),
|
||||
genre: { id: "genre101", name: "some genre" },
|
||||
}),
|
||||
artist: anArtist({ name: "great artist", id: uuid() }),
|
||||
});
|
||||
|
||||
@@ -206,8 +213,8 @@ describe("track", () => {
|
||||
artist: someTrack.artist.name,
|
||||
artistId: someTrack.artist.id,
|
||||
duration: someTrack.duration,
|
||||
genre: someTrack.album.genre,
|
||||
// genreId
|
||||
genre: someTrack.album.genre?.name,
|
||||
genreId: someTrack.album.genre?.id,
|
||||
trackNumber: someTrack.number,
|
||||
},
|
||||
});
|
||||
@@ -559,17 +566,20 @@ describe("api", () => {
|
||||
|
||||
describe("asking for a genres", () => {
|
||||
const artist1 = anArtist({
|
||||
albums: [anAlbum({ genre: "Pop" }), anAlbum({ genre: "Rock" })],
|
||||
albums: [
|
||||
anAlbum({ genre: POP }),
|
||||
anAlbum({ genre: ROCK }),
|
||||
],
|
||||
});
|
||||
const artist2 = anArtist({
|
||||
albums: [
|
||||
anAlbum({ genre: "Trip-Hop" }),
|
||||
anAlbum({ genre: "Punk" }),
|
||||
anAlbum({ genre: "Pop" }),
|
||||
anAlbum({ genre: TRIP_HOP }),
|
||||
anAlbum({ genre: PUNK }),
|
||||
anAlbum({ genre: POP }),
|
||||
],
|
||||
});
|
||||
|
||||
const expectedGenres = ["Pop", "Punk", "Rock", "Trip-Hop"];
|
||||
const expectedGenres = [POP, PUNK, ROCK, TRIP_HOP];
|
||||
|
||||
beforeEach(() => {
|
||||
musicService.hasArtists(artist1, artist2);
|
||||
@@ -586,8 +596,8 @@ describe("api", () => {
|
||||
getMetadataResult({
|
||||
mediaCollection: expectedGenres.map((genre) => ({
|
||||
itemType: "container",
|
||||
id: `genre:${genre}`,
|
||||
title: genre,
|
||||
id: `genre:${genre.id}`,
|
||||
title: genre.name,
|
||||
})),
|
||||
index: 0,
|
||||
total: expectedGenres.length,
|
||||
@@ -605,10 +615,10 @@ describe("api", () => {
|
||||
});
|
||||
expect(result[0]).toEqual(
|
||||
getMetadataResult({
|
||||
mediaCollection: ["Punk", "Rock"].map((genre) => ({
|
||||
mediaCollection: [PUNK, ROCK].map((genre) => ({
|
||||
itemType: "container",
|
||||
id: `genre:${genre}`,
|
||||
title: genre,
|
||||
id: `genre:${genre.id}`,
|
||||
title: genre.name,
|
||||
})),
|
||||
index: 1,
|
||||
total: expectedGenres.length,
|
||||
|
||||
Reference in New Issue
Block a user