5ecbe31a06
Signed-off-by: Deluan <deluan@navidrome.org>
200 lines
5.9 KiB
Go
200 lines
5.9 KiB
Go
package e2e
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"github.com/navidrome/navidrome/conf"
|
|
"github.com/navidrome/navidrome/conf/configtest"
|
|
"github.com/navidrome/navidrome/model"
|
|
"github.com/navidrome/navidrome/server/subsonic/responses"
|
|
. "github.com/onsi/ginkgo/v2"
|
|
. "github.com/onsi/gomega"
|
|
)
|
|
|
|
var _ = Describe("Media Retrieval Endpoints", Ordered, func() {
|
|
BeforeAll(func() {
|
|
setupTestDB()
|
|
})
|
|
|
|
Describe("Stream", func() {
|
|
var trackID string
|
|
|
|
BeforeAll(func() {
|
|
// All test tracks are mp3 at 320kbps
|
|
songs, err := ds.MediaFile(ctx).GetAll(model.QueryOptions{Max: 1, Sort: "title"})
|
|
Expect(err).ToNot(HaveOccurred())
|
|
Expect(songs).ToNot(BeEmpty())
|
|
trackID = songs[0].ID
|
|
})
|
|
|
|
It("returns error when id parameter is missing", func() {
|
|
resp := doReq("stream")
|
|
|
|
Expect(resp.Status).To(Equal(responses.StatusFailed))
|
|
Expect(resp.Error).ToNot(BeNil())
|
|
})
|
|
|
|
It("streams raw when no format or bitrate specified", func() {
|
|
w := doRawReq("stream", "id", trackID)
|
|
|
|
Expect(w.Code).To(Equal(http.StatusOK))
|
|
Expect(streamerSpy.LastRequest.Format).To(Equal("raw"))
|
|
})
|
|
|
|
It("streams raw when format=raw", func() {
|
|
w := doRawReq("stream", "id", trackID, "format", "raw")
|
|
|
|
Expect(w.Code).To(Equal(http.StatusOK))
|
|
Expect(streamerSpy.LastRequest.Format).To(Equal("raw"))
|
|
})
|
|
|
|
It("transcodes to different format with bitrate", func() {
|
|
w := doRawReq("stream", "id", trackID, "format", "opus", "maxBitRate", "128")
|
|
|
|
Expect(w.Code).To(Equal(http.StatusOK))
|
|
Expect(streamerSpy.LastRequest.Format).To(Equal("opus"))
|
|
Expect(streamerSpy.LastRequest.BitRate).To(Equal(128))
|
|
})
|
|
|
|
It("downsamples when only maxBitRate is specified (lower than source)", func() {
|
|
DeferCleanup(configtest.SetupConfig())
|
|
conf.Server.DefaultDownsamplingFormat = "opus"
|
|
|
|
w := doRawReq("stream", "id", trackID, "maxBitRate", "128")
|
|
|
|
Expect(w.Code).To(Equal(http.StatusOK))
|
|
Expect(streamerSpy.LastRequest.Format).To(Equal("opus"))
|
|
Expect(streamerSpy.LastRequest.BitRate).To(Equal(128))
|
|
})
|
|
|
|
It("streams raw when maxBitRate is higher than source", func() {
|
|
w := doRawReq("stream", "id", trackID, "maxBitRate", "999")
|
|
|
|
Expect(w.Code).To(Equal(http.StatusOK))
|
|
Expect(streamerSpy.LastRequest.Format).To(Equal("raw"))
|
|
})
|
|
|
|
It("streams raw when format matches source and no bitrate reduction", func() {
|
|
w := doRawReq("stream", "id", trackID, "format", "mp3", "maxBitRate", "320")
|
|
|
|
Expect(w.Code).To(Equal(http.StatusOK))
|
|
Expect(streamerSpy.LastRequest.Format).To(Equal("raw"))
|
|
})
|
|
|
|
It("transcodes when same format but lower bitrate", func() {
|
|
w := doRawReq("stream", "id", trackID, "format", "mp3", "maxBitRate", "128")
|
|
|
|
Expect(w.Code).To(Equal(http.StatusOK))
|
|
Expect(streamerSpy.LastRequest.Format).To(Equal("mp3"))
|
|
Expect(streamerSpy.LastRequest.BitRate).To(Equal(128))
|
|
})
|
|
|
|
It("falls back to default downsampling format for unknown format", func() {
|
|
w := doRawReq("stream", "id", trackID, "format", "xyz")
|
|
|
|
Expect(w.Code).To(Equal(http.StatusOK))
|
|
Expect(streamerSpy.LastRequest.Format).To(Equal("opus"))
|
|
})
|
|
|
|
It("passes timeOffset through", func() {
|
|
w := doRawReq("stream", "id", trackID, "format", "opus", "maxBitRate", "128", "timeOffset", "30")
|
|
|
|
Expect(w.Code).To(Equal(http.StatusOK))
|
|
Expect(streamerSpy.LastRequest.Format).To(Equal("opus"))
|
|
Expect(streamerSpy.LastRequest.Offset).To(Equal(30))
|
|
})
|
|
})
|
|
|
|
Describe("Download", func() {
|
|
var trackID string
|
|
|
|
BeforeAll(func() {
|
|
// All test tracks are mp3 at 320kbps
|
|
songs, err := ds.MediaFile(ctx).GetAll(model.QueryOptions{Max: 1, Sort: "title"})
|
|
Expect(err).ToNot(HaveOccurred())
|
|
Expect(songs).ToNot(BeEmpty())
|
|
trackID = songs[0].ID
|
|
})
|
|
|
|
It("returns error when id parameter is missing", func() {
|
|
resp := doReq("download")
|
|
|
|
Expect(resp.Status).To(Equal(responses.StatusFailed))
|
|
Expect(resp.Error).ToNot(BeNil())
|
|
})
|
|
|
|
It("downloads raw when no format specified and AutoTranscodeDownload is false", func() {
|
|
DeferCleanup(configtest.SetupConfig())
|
|
conf.Server.EnableDownloads = true
|
|
conf.Server.AutoTranscodeDownload = false
|
|
|
|
w := doRawReq("download", "id", trackID)
|
|
|
|
Expect(w.Code).To(Equal(http.StatusOK))
|
|
Expect(streamerSpy.LastRequest.Format).To(Equal("raw"))
|
|
})
|
|
|
|
It("downloads with explicit format and bitrate", func() {
|
|
DeferCleanup(configtest.SetupConfig())
|
|
conf.Server.EnableDownloads = true
|
|
|
|
w := doRawReq("download", "id", trackID, "format", "opus", "bitrate", "128")
|
|
|
|
Expect(w.Code).To(Equal(http.StatusOK))
|
|
Expect(streamerSpy.LastRequest.Format).To(Equal("opus"))
|
|
Expect(streamerSpy.LastRequest.BitRate).To(Equal(128))
|
|
})
|
|
|
|
It("returns error when downloads are disabled", func() {
|
|
DeferCleanup(configtest.SetupConfig())
|
|
conf.Server.EnableDownloads = false
|
|
|
|
resp := doReq("download", "id", trackID)
|
|
|
|
Expect(resp.Status).To(Equal(responses.StatusFailed))
|
|
})
|
|
})
|
|
|
|
Describe("GetCoverArt", func() {
|
|
It("handles request without error", func() {
|
|
w := doRawReq("getCoverArt")
|
|
|
|
Expect(w.Code).To(Equal(http.StatusOK))
|
|
})
|
|
})
|
|
|
|
Describe("GetAvatar", func() {
|
|
It("returns placeholder avatar when gravatar disabled", func() {
|
|
w := doRawReq("getAvatar", "username", "admin")
|
|
|
|
Expect(w.Code).To(Equal(http.StatusOK))
|
|
})
|
|
})
|
|
|
|
Describe("GetLyrics", func() {
|
|
It("returns empty lyrics when no match found", func() {
|
|
resp := doReq("getLyrics", "artist", "NonExistentArtist", "title", "NonExistentTitle")
|
|
|
|
Expect(resp.Status).To(Equal(responses.StatusOK))
|
|
Expect(resp.Lyrics).ToNot(BeNil())
|
|
Expect(resp.Lyrics.Value).To(BeEmpty())
|
|
})
|
|
})
|
|
|
|
Describe("GetLyricsBySongId", func() {
|
|
It("returns error when id parameter is missing", func() {
|
|
resp := doReq("getLyricsBySongId")
|
|
|
|
Expect(resp.Status).To(Equal(responses.StatusFailed))
|
|
Expect(resp.Error).ToNot(BeNil())
|
|
})
|
|
|
|
It("returns error for non-existent song id", func() {
|
|
resp := doReq("getLyricsBySongId", "id", "non-existent-id")
|
|
|
|
Expect(resp.Status).To(Equal(responses.StatusFailed))
|
|
Expect(resp.Error).ToNot(BeNil())
|
|
})
|
|
})
|
|
})
|