Ability to stream a track from navidrome

This commit is contained in:
simojenki
2021-03-11 19:27:50 +11:00
parent 081819f12b
commit 9f484d5c01
11 changed files with 1087 additions and 277 deletions

View File

@@ -1,4 +1,6 @@
import { v4 as uuid } from "uuid";
import request from "supertest";
import { MusicService } from "../src/music_service";
import makeServer from "../src/server";
import { SONOS_DISABLED, Sonos, Device } from "../src/sonos";
@@ -185,4 +187,187 @@ describe("server", () => {
});
});
});
describe("/stream", () => {
const musicService = {
login: jest.fn(),
};
const musicLibrary = {
stream: jest.fn(),
};
const server = makeServer(
(jest.fn() as unknown) as Sonos,
aService(),
"http://localhost:1234",
(musicService as unknown) as MusicService
);
const authToken = uuid();
const trackId = uuid();
describe("when sonos does not ask for a range", () => {
describe("when the music service returns a 200", () => {
it("should return a 200 with the data", async () => {
const stream = {
status: 200,
headers: {
"content-type": "audio/mp3",
"content-length": "222",
"accept-ranges": "bytes",
"content-range": "-100",
},
data: Buffer.from("some track", "ascii"),
};
musicService.login.mockResolvedValue(musicLibrary);
musicLibrary.stream.mockResolvedValue(stream);
const res = await request(server)
.get(`/stream/track/${trackId}`)
.set("bonob-token", authToken);
console.log("testing finished watiting");
expect(res.status).toEqual(stream.status);
expect(res.header["content-type"]).toEqual(
stream.headers["content-type"]
);
expect(res.header["accept-ranges"]).toEqual(
stream.headers["accept-ranges"]
);
expect(res.header["content-range"]).toEqual(
stream.headers["content-range"]
);
expect(musicService.login).toHaveBeenCalledWith(authToken);
expect(musicLibrary.stream).toHaveBeenCalledWith({ trackId });
});
});
describe("when the music service returns a 206", () => {
it("should return a 206 with the data", async () => {
const stream = {
status: 206,
headers: {
"content-type": "audio/ogg",
"content-length": "333",
"accept-ranges": "bytez",
"content-range": "100-200",
},
data: Buffer.from("some other track", "ascii"),
};
musicService.login.mockResolvedValue(musicLibrary);
musicLibrary.stream.mockResolvedValue(stream);
const res = await request(server)
.get(`/stream/track/${trackId}`)
.set("bonob-token", authToken);
console.log("testing finished watiting");
expect(res.status).toEqual(stream.status);
expect(res.header["content-type"]).toEqual(
stream.headers["content-type"]
);
// expect(res.header["content-length"]).toEqual(stream.headers["content-length"]);
expect(res.header["accept-ranges"]).toEqual(
stream.headers["accept-ranges"]
);
expect(res.header["content-range"]).toEqual(
stream.headers["content-range"]
);
expect(musicService.login).toHaveBeenCalledWith(authToken);
expect(musicLibrary.stream).toHaveBeenCalledWith({ trackId });
});
});
});
describe("when sonos does ask for a range", () => {
describe("when the music service returns a 200", () => {
it("should return a 200 with the data", async () => {
const stream = {
status: 200,
headers: {
"content-type": "audio/mp3",
"content-length": "222",
"accept-ranges": "bytes",
"content-range": "-100",
},
data: Buffer.from("some track", "ascii"),
};
musicService.login.mockResolvedValue(musicLibrary);
musicLibrary.stream.mockResolvedValue(stream);
const res = await request(server)
.get(`/stream/track/${trackId}`)
.set("bonob-token", authToken)
.set("Range", "3000-4000");
console.log("testing finished watiting");
expect(res.status).toEqual(stream.status);
expect(res.header["content-type"]).toEqual(
stream.headers["content-type"]
);
expect(res.header["accept-ranges"]).toEqual(
stream.headers["accept-ranges"]
);
expect(res.header["content-range"]).toEqual(
stream.headers["content-range"]
);
expect(musicService.login).toHaveBeenCalledWith(authToken);
expect(musicLibrary.stream).toHaveBeenCalledWith({
trackId,
range: "3000-4000",
});
});
});
describe("when the music service returns a 206", () => {
it("should return a 206 with the data", async () => {
const stream = {
status: 206,
headers: {
"content-type": "audio/ogg",
"content-length": "333",
"accept-ranges": "bytez",
"content-range": "100-200",
},
data: Buffer.from("some other track", "ascii"),
};
musicService.login.mockResolvedValue(musicLibrary);
musicLibrary.stream.mockResolvedValue(stream);
const res = await request(server)
.get(`/stream/track/${trackId}`)
.set("bonob-token", authToken)
.set("Range", "4000-5000");
console.log("testing finished watiting");
expect(res.status).toEqual(stream.status);
expect(res.header["content-type"]).toEqual(
stream.headers["content-type"]
);
expect(res.header["accept-ranges"]).toEqual(
stream.headers["accept-ranges"]
);
expect(res.header["content-range"]).toEqual(
stream.headers["content-range"]
);
expect(musicService.login).toHaveBeenCalledWith(authToken);
expect(musicLibrary.stream).toHaveBeenCalledWith({
trackId,
range: "4000-5000",
});
});
});
});
});
});