Files
bonob/tests/builders.ts
Simon J 6321cb71a4 URN for image info (#78)
* Allow music service to return a URN identifying cover art for an entity

* Fix bug with playlist cover art rending same album multiple times
2021-11-15 17:33:51 +11:00

329 lines
8.0 KiB
TypeScript

import { SonosDevice } from "@svrooij/sonos/lib";
import { v4 as uuid } from "uuid";
import randomstring from "randomstring";
import { Credentials } from "../src/smapi";
import { Service, Device } from "../src/sonos";
import {
Album,
Artist,
Track,
albumToAlbumSummary,
artistToArtistSummary,
PlaylistSummary,
Playlist,
SimilarArtist,
AlbumSummary,
} from "../src/music_service";
import { b64Encode } from "../src/b64";
import { artistImageURN } from "../src/subsonic";
const randomInt = (max: number) => Math.floor(Math.random() * Math.floor(max));
const randomIpAddress = () => `127.0.${randomInt(255)}.${randomInt(255)}`;
export const aService = (fields: Partial<Service> = {}): Service => ({
sid: randomInt(500),
name: `Test Music Service ${uuid()}`,
uri: "https://sonos-test.example.com/",
secureUri: "https://sonos-test.example.com/",
strings: {
uri: "https://sonos-test.example.com/strings.xml",
version: "22",
},
presentation: {
uri: "https://sonos-test.example.com/presentation.xml",
version: "33",
},
pollInterval: 1200,
authType: "DeviceLink",
...fields,
});
export function aPlaylistSummary(
fields: Partial<PlaylistSummary> = {}
): PlaylistSummary {
return {
id: `playlist-${uuid()}`,
name: `playlistname-${randomstring.generate()}`,
...fields,
};
}
export function aPlaylist(fields: Partial<Playlist> = {}): Playlist {
return {
id: `playlist-${uuid()}`,
name: `playlist-${randomstring.generate()}`,
entries: [aTrack(), aTrack()],
...fields,
};
}
export function aDevice(fields: Partial<Device> = {}): Device {
return {
name: `device-${uuid()}`,
group: `group-${uuid()}`,
ip: randomIpAddress(),
port: randomInt(10_000),
...fields,
};
}
export function aSonosDevice(fields: Partial<SonosDevice> = {}): SonosDevice {
return {
Name: `device-${uuid()}`,
GroupName: `group-${uuid()}`,
Host: randomIpAddress(),
Port: randomInt(10_000),
...fields,
} as SonosDevice;
}
export function getAppLinkMessage() {
return {
householdId: "",
hardware: "",
osVersion: "",
sonosAppName: "",
callbackPath: "",
};
}
export function someCredentials(token: string): Credentials {
return {
loginToken: {
token,
householdId: "hh1",
},
deviceId: "d1",
deviceProvider: "dp1",
};
}
export function aSimilarArtist(
fields: Partial<SimilarArtist> = {}
): SimilarArtist {
const id = fields.id || uuid();
return {
id,
name: `Similar Artist ${id}`,
image: artistImageURN({ artistId: id }),
inLibrary: true,
...fields,
};
}
export function anArtist(fields: Partial<Artist> = {}): Artist {
const id = fields.id || uuid();
const artist = {
id,
name: `Artist ${id}`,
albums: [anAlbum(), anAlbum(), anAlbum()],
image: { system: "subsonic", resource: `art:${id}` },
similarArtists: [
aSimilarArtist({ id: uuid(), name: "Similar artist1", inLibrary: true }),
aSimilarArtist({ id: uuid(), name: "Similar artist2", inLibrary: true }),
aSimilarArtist({
id: "-1",
name: "Artist not in library",
inLibrary: false,
}),
],
...fields,
};
artist.albums.forEach((album) => {
album.artistId = artist.id;
album.artistName = artist.name;
});
return artist;
}
export const aGenre = (name: string) => ({ id: b64Encode(name), name });
export const HIP_HOP = aGenre("Hip-Hop");
export const METAL = aGenre("Metal");
export const NEW_WAVE = aGenre("New Wave");
export const POP = aGenre("Pop");
export const POP_ROCK = aGenre("Pop Rock");
export const REGGAE = aGenre("Reggae");
export const ROCK = aGenre("Rock");
export const SKA = aGenre("Ska");
export const PUNK = aGenre("Punk");
export const TRIP_HOP = aGenre("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();
const artist = anArtist();
const genre = fields.genre || randomGenre();
const rating = { love: false, stars: Math.floor(Math.random() * 5) };
return {
id,
name: `Track ${id}`,
mimeType: `audio/mp3-${id}`,
duration: randomInt(500),
number: randomInt(100),
genre,
artist: artistToArtistSummary(artist),
album: albumToAlbumSummary(
anAlbum({ artistId: artist.id, artistName: artist.name, genre })
),
coverArt: { system: "subsonic", resource: `art:${uuid()}`},
rating,
...fields,
};
}
export function anAlbum(fields: Partial<Album> = {}): Album {
const id = uuid();
return {
id,
name: `Album ${id}`,
genre: randomGenre(),
year: `19${randomInt(99)}`,
artistId: `Artist ${uuid()}`,
artistName: `Artist ${randomstring.generate()}`,
coverArt: { system: "subsonic", resource: `art:${uuid()}` },
...fields,
};
};
export function anAlbumSummary(fields: Partial<AlbumSummary> = {}): AlbumSummary {
const id = uuid();
return {
id,
name: `Album ${id}`,
year: `19${randomInt(99)}`,
genre: randomGenre(),
coverArt: { system: "subsonic", resource: `art:${uuid()}` },
artistId: `Artist ${uuid()}`,
artistName: `Artist ${randomstring.generate()}`,
...fields
}
};
export const BLONDIE_ID = uuid();
export const BLONDIE_NAME = "Blondie";
export const BLONDIE: Artist = {
id: BLONDIE_ID,
name: BLONDIE_NAME,
albums: [
{
id: uuid(),
name: "Blondie",
year: "1976",
genre: NEW_WAVE,
artistId: BLONDIE_ID,
artistName: BLONDIE_NAME,
coverArt: { system: "subsonic", resource: `art:${uuid()}`},
},
{
id: uuid(),
name: "Parallel Lines",
year: "1978",
genre: POP_ROCK,
artistId: BLONDIE_ID,
artistName: BLONDIE_NAME,
coverArt: { system: "subsonic", resource: `art:${uuid()}`},
},
],
image: { system: "external", resource: "http://localhost:1234/images/blondie.jpg" },
similarArtists: [],
};
export const BOB_MARLEY_ID = uuid();
export const BOB_MARLEY_NAME = "Bob Marley";
export const BOB_MARLEY: Artist = {
id: BOB_MARLEY_ID,
name: BOB_MARLEY_NAME,
albums: [
{
id: uuid(),
name: "Burin'",
year: "1973",
genre: REGGAE,
artistId: BOB_MARLEY_ID,
artistName: BOB_MARLEY_NAME,
coverArt: { system: "subsonic", resource: `art:${uuid()}`},
},
{
id: uuid(),
name: "Exodus",
year: "1977",
genre: REGGAE,
artistId: BOB_MARLEY_ID,
artistName: BOB_MARLEY_NAME,
coverArt: { system: "subsonic", resource: `art:${uuid()}`},
},
{
id: uuid(),
name: "Kaya",
year: "1978",
genre: SKA,
artistId: BOB_MARLEY_ID,
artistName: BOB_MARLEY_NAME,
coverArt: { system: "subsonic", resource: `art:${uuid()}`},
},
],
image: { system: "subsonic", resource: BOB_MARLEY_ID },
similarArtists: [],
};
export const MADONNA_ID = uuid();
export const MADONNA_NAME = "Madonna";
export const MADONNA: Artist = {
id: MADONNA_ID,
name: MADONNA_NAME,
albums: [],
image: {
system: "external",
resource: "http://localhost:1234/images/madonna.jpg",
},
similarArtists: [],
};
export const METALLICA_ID = uuid();
export const METALLICA_NAME = "Metallica";
export const METALLICA: Artist = {
id: METALLICA_ID,
name: METALLICA_NAME,
albums: [
{
id: uuid(),
name: "Ride the Lightening",
year: "1984",
genre: METAL,
artistId: METALLICA_ID,
artistName: METALLICA_NAME,
coverArt: { system: "subsonic", resource: `art:${uuid()}`},
},
{
id: uuid(),
name: "Master of Puppets",
year: "1986",
genre: METAL,
artistId: METALLICA_ID,
artistName: METALLICA_NAME,
coverArt: { system: "subsonic", resource: `art:${uuid()}`},
},
],
image: { system: "subsonic", resource: METALLICA_ID },
similarArtists: [],
};
export const ALL_ARTISTS = [BOB_MARLEY, BLONDIE, MADONNA, METALLICA];
export const ALL_ALBUMS = ALL_ARTISTS.flatMap((it) => it.albums || []);