Feature/no more sharp (#193)

* Playlist icons working as rendered by ND

* remove duplication in cover art image url creation

* Remove unused ability to create collages of images
This commit is contained in:
Simon J
2024-02-05 17:22:27 +11:00
committed by GitHub
parent 66c248fe44
commit 6bf89b87e2
6 changed files with 74 additions and 752 deletions

View File

@@ -2,9 +2,7 @@ import { v4 as uuid } from "uuid";
import dayjs from "dayjs";
import request from "supertest";
import Image from "image-js";
import fs from "fs";
import { either as E, taskEither as TE } from "fp-ts";
import path from "path";
import { AuthFailure, MusicService } from "../src/music_service";
import makeServer, {
@@ -1323,279 +1321,6 @@ describe("server", () => {
});
});
describe("fetching multiple images as a collage", () => {
const png = fs.readFileSync(
path.join(
__dirname,
"..",
"docs",
"images",
"chartreuseFuchsia.png"
)
);
describe("fetching a collage of 4 when all are available", () => {
it("should return the image and a 200", async () => {
const urns = [
"art:1",
"art:2",
"art:3",
"art:4",
].map(resource => ({ system:"subsonic", resource }));
musicService.login.mockResolvedValue(musicLibrary);
urns.forEach((_) => {
musicLibrary.coverArt.mockResolvedValueOnce(
coverArtResponse({
data: png,
})
);
});
const res = await request(server)
.get(
`/art/${urns.map(it => encodeURIComponent(formatForURL(it))).join(
"&"
)}/size/200?${BONOB_ACCESS_TOKEN_HEADER}=${apiToken}`
)
.set(BONOB_ACCESS_TOKEN_HEADER, apiToken);
expect(res.status).toEqual(200);
expect(res.header["content-type"]).toEqual("image/png");
expect(musicService.login).toHaveBeenCalledWith(serviceToken);
urns.forEach((it) => {
expect(musicLibrary.coverArt).toHaveBeenCalledWith(it, 200);
});
const image = await Image.load(res.body);
expect(image.width).toEqual(200);
expect(image.height).toEqual(200);
});
});
describe("fetching a collage of 4, however only 1 is available", () => {
it("should return the single image", async () => {
const urns = ["art:1", "art:2", "art:3", "art:4"].map(resource => ({ system:"subsonic", resource }));
musicService.login.mockResolvedValue(musicLibrary);
musicLibrary.coverArt.mockResolvedValueOnce(undefined);
musicLibrary.coverArt.mockResolvedValueOnce(undefined);
musicLibrary.coverArt.mockResolvedValueOnce(undefined);
musicLibrary.coverArt.mockResolvedValueOnce(
coverArtResponse({
data: png,
contentType: "image/some-mime-type",
})
);
const res = await request(server)
.get(
`/art/${urns.map(it => encodeURIComponent(formatForURL(it))).join(
"&"
)}/size/200?${BONOB_ACCESS_TOKEN_HEADER}=${apiToken}`
)
.set(BONOB_ACCESS_TOKEN_HEADER, apiToken);
expect(res.status).toEqual(200);
expect(res.header["content-type"]).toEqual(
"image/some-mime-type"
);
});
});
describe("fetching a collage of 4 and all are missing", () => {
it("should return a 404", async () => {
const urns = ["art:1", "art:2", "art:3", "art:4"].map(resource => ({ system:"subsonic", resource }));
musicService.login.mockResolvedValue(musicLibrary);
urns.forEach((_) => {
musicLibrary.coverArt.mockResolvedValueOnce(undefined);
});
const res = await request(server)
.get(
`/art/${urns.map(it => encodeURIComponent(formatForURL(it))).join(
"&"
)}/size/200?${BONOB_ACCESS_TOKEN_HEADER}=${apiToken}`
)
.set(BONOB_ACCESS_TOKEN_HEADER, apiToken);
expect(res.status).toEqual(404);
});
});
describe("fetching a collage of 9 when all are available", () => {
it("should return the image and a 200", async () => {
const urns = [
"artist:1",
"artist:2",
"coverArt:3",
"artist:4",
"artist:5",
"artist:6",
"artist:7",
"artist:8",
"artist:9",
].map(resource => ({ system:"subsonic", resource }));
musicService.login.mockResolvedValue(musicLibrary);
urns.forEach((_) => {
musicLibrary.coverArt.mockResolvedValueOnce(
coverArtResponse({
data: png,
})
);
});
const res = await request(server)
.get(
`/art/${urns.map(it => encodeURIComponent(formatForURL(it))).join(
"&"
)}/size/180?${BONOB_ACCESS_TOKEN_HEADER}=${apiToken}`
)
.set(BONOB_ACCESS_TOKEN_HEADER, apiToken);
expect(res.status).toEqual(200);
expect(res.header["content-type"]).toEqual("image/png");
expect(musicService.login).toHaveBeenCalledWith(serviceToken);
urns.forEach((it) => {
expect(musicLibrary.coverArt).toHaveBeenCalledWith(it, 180);
});
const image = await Image.load(res.body);
expect(image.width).toEqual(180);
expect(image.height).toEqual(180);
});
});
describe("fetching a collage of 9 when only 2 are available", () => {
it("should still return an image and a 200", async () => {
const urns = [
"artist:1",
"artist:2",
"artist:3",
"artist:4",
"artist:5",
"artist:6",
"artist:7",
"artist:8",
"artist:9",
].map(resource => ({ system:"subsonic", resource }));
musicService.login.mockResolvedValue(musicLibrary);
musicLibrary.coverArt.mockResolvedValueOnce(
coverArtResponse({
data: png,
})
);
musicLibrary.coverArt.mockResolvedValueOnce(
coverArtResponse({
data: png,
})
);
musicLibrary.coverArt.mockResolvedValueOnce(undefined);
musicLibrary.coverArt.mockResolvedValueOnce(undefined);
musicLibrary.coverArt.mockResolvedValueOnce(undefined);
musicLibrary.coverArt.mockResolvedValueOnce(undefined);
musicLibrary.coverArt.mockResolvedValueOnce(undefined);
musicLibrary.coverArt.mockResolvedValueOnce(undefined);
musicLibrary.coverArt.mockResolvedValueOnce(undefined);
const res = await request(server)
.get(
`/art/${urns.map(it => encodeURIComponent(formatForURL(it))).join(
"&"
)}/size/180?${BONOB_ACCESS_TOKEN_HEADER}=${apiToken}`
)
.set(BONOB_ACCESS_TOKEN_HEADER, apiToken);
expect(res.status).toEqual(200);
expect(res.header["content-type"]).toEqual("image/png");
expect(musicService.login).toHaveBeenCalledWith(serviceToken);
urns.forEach((urn) => {
expect(musicLibrary.coverArt).toHaveBeenCalledWith(urn, 180);
});
const image = await Image.load(res.body);
expect(image.width).toEqual(180);
expect(image.height).toEqual(180);
});
});
describe("fetching a collage of 11", () => {
it("should still return an image and a 200, though will only display 9", async () => {
const urns = [
"artist:1",
"artist:2",
"artist:3",
"artist:4",
"artist:5",
"artist:6",
"artist:7",
"artist:8",
"artist:9",
"artist:10",
"artist:11",
].map(resource => ({ system:"subsonic", resource }));
musicService.login.mockResolvedValue(musicLibrary);
urns.forEach((_) => {
musicLibrary.coverArt.mockResolvedValueOnce(
coverArtResponse({
data: png,
})
);
});
const res = await request(server)
.get(
`/art/${urns.map(it => encodeURIComponent(formatForURL(it))).join(
"&"
)}/size/180?${BONOB_ACCESS_TOKEN_HEADER}=${apiToken}`
)
.set(BONOB_ACCESS_TOKEN_HEADER, apiToken);
expect(res.status).toEqual(200);
expect(res.header["content-type"]).toEqual("image/png");
expect(musicService.login).toHaveBeenCalledWith(serviceToken);
urns.forEach((it) => {
expect(musicLibrary.coverArt).toHaveBeenCalledWith(it, 180);
});
const image = await Image.load(res.body);
expect(image.width).toEqual(180);
expect(image.height).toEqual(180);
});
});
describe("when the image is not available", () => {
it("should return a 404", async () => {
const coverArtURN = { system:"subsonic", resource:"art:404"};
musicService.login.mockResolvedValue(musicLibrary);
musicLibrary.coverArt.mockResolvedValue(undefined);
const res = await request(server)
.get(
`/art/${encodeURIComponent(formatForURL(coverArtURN))}/size/180?${BONOB_ACCESS_TOKEN_HEADER}=${apiToken}`
)
.set(BONOB_ACCESS_TOKEN_HEADER, apiToken);
expect(res.status).toEqual(404);
});
});
});
describe("when there is an error", () => {
it("should return a 500", async () => {
musicService.login.mockResolvedValue(musicLibrary);