2020-01-20 00:21:44 +01:00
|
|
|
package subsonic
|
2020-01-09 02:45:07 +01:00
|
|
|
|
2020-01-10 03:58:03 +01:00
|
|
|
import (
|
2020-11-17 19:30:37 +01:00
|
|
|
"bytes"
|
2020-01-22 14:32:31 +01:00
|
|
|
"context"
|
2020-01-10 03:58:03 +01:00
|
|
|
"errors"
|
|
|
|
"io"
|
|
|
|
"net/http/httptest"
|
2022-12-27 20:30:00 +01:00
|
|
|
"time"
|
2020-01-10 03:58:03 +01:00
|
|
|
|
2023-02-01 00:22:49 +01:00
|
|
|
"github.com/navidrome/navidrome/core/artwork"
|
2021-10-19 22:33:06 +02:00
|
|
|
"github.com/navidrome/navidrome/log"
|
2020-01-24 01:44:08 +01:00
|
|
|
"github.com/navidrome/navidrome/model"
|
2020-11-13 20:57:49 +01:00
|
|
|
"github.com/navidrome/navidrome/tests"
|
2022-07-26 22:47:16 +02:00
|
|
|
. "github.com/onsi/ginkgo/v2"
|
2020-01-10 03:58:03 +01:00
|
|
|
. "github.com/onsi/gomega"
|
|
|
|
)
|
|
|
|
|
|
|
|
var _ = Describe("MediaRetrievalController", func() {
|
2022-11-21 18:57:56 +01:00
|
|
|
var router *Router
|
2021-10-19 22:33:06 +02:00
|
|
|
var ds model.DataStore
|
|
|
|
mockRepo := &mockedMediaFile{}
|
2020-07-31 15:31:19 +02:00
|
|
|
var artwork *fakeArtwork
|
2020-01-10 03:58:03 +01:00
|
|
|
var w *httptest.ResponseRecorder
|
|
|
|
|
|
|
|
BeforeEach(func() {
|
2021-10-19 22:33:06 +02:00
|
|
|
ds = &tests.MockDataStore{
|
|
|
|
MockedMediaFile: mockRepo,
|
|
|
|
}
|
2020-07-31 15:31:19 +02:00
|
|
|
artwork = &fakeArtwork{}
|
2023-01-22 20:38:55 +01:00
|
|
|
router = New(ds, artwork, nil, nil, nil, nil, nil, nil, nil, nil, nil)
|
2020-01-10 03:58:03 +01:00
|
|
|
w = httptest.NewRecorder()
|
|
|
|
})
|
|
|
|
|
|
|
|
Describe("GetCoverArt", func() {
|
|
|
|
It("should return data for that id", func() {
|
2020-07-31 15:31:19 +02:00
|
|
|
artwork.data = "image data"
|
2020-01-27 21:10:46 +01:00
|
|
|
r := newGetRequest("id=34", "size=128")
|
2022-11-21 18:57:56 +01:00
|
|
|
_, err := router.GetCoverArt(w, r)
|
2020-01-10 03:58:03 +01:00
|
|
|
|
|
|
|
Expect(err).To(BeNil())
|
2020-07-31 15:31:19 +02:00
|
|
|
Expect(artwork.recvId).To(Equal("34"))
|
|
|
|
Expect(artwork.recvSize).To(Equal(128))
|
|
|
|
Expect(w.Body.String()).To(Equal(artwork.data))
|
2020-01-10 03:58:03 +01:00
|
|
|
})
|
|
|
|
|
2021-05-29 17:37:00 +02:00
|
|
|
It("should return placeholder if id parameter is missing (mimicking Subsonic)", func() {
|
2020-01-27 21:10:46 +01:00
|
|
|
r := newGetRequest()
|
2022-11-21 18:57:56 +01:00
|
|
|
_, err := router.GetCoverArt(w, r)
|
2020-01-10 03:58:03 +01:00
|
|
|
|
2021-05-29 17:37:00 +02:00
|
|
|
Expect(err).To(BeNil())
|
|
|
|
Expect(w.Body.String()).To(Equal(artwork.data))
|
2020-01-10 03:58:03 +01:00
|
|
|
})
|
|
|
|
|
|
|
|
It("should fail when the file is not found", func() {
|
2020-07-31 15:31:19 +02:00
|
|
|
artwork.err = model.ErrNotFound
|
2020-01-27 21:10:46 +01:00
|
|
|
r := newGetRequest("id=34", "size=128")
|
2022-11-21 18:57:56 +01:00
|
|
|
_, err := router.GetCoverArt(w, r)
|
2020-01-10 03:58:03 +01:00
|
|
|
|
2020-07-31 15:31:19 +02:00
|
|
|
Expect(err).To(MatchError("Artwork not found"))
|
2020-01-10 03:58:03 +01:00
|
|
|
})
|
|
|
|
|
|
|
|
It("should fail when there is an unknown error", func() {
|
2020-07-31 15:31:19 +02:00
|
|
|
artwork.err = errors.New("weird error")
|
2020-01-27 21:10:46 +01:00
|
|
|
r := newGetRequest("id=34", "size=128")
|
2022-11-21 18:57:56 +01:00
|
|
|
_, err := router.GetCoverArt(w, r)
|
2020-01-10 03:58:03 +01:00
|
|
|
|
2020-10-27 20:23:29 +01:00
|
|
|
Expect(err).To(MatchError("weird error"))
|
2020-01-10 03:58:03 +01:00
|
|
|
})
|
|
|
|
})
|
2021-10-19 22:33:06 +02:00
|
|
|
|
|
|
|
Describe("GetLyrics", func() {
|
|
|
|
It("should return data for given artist & title", func() {
|
|
|
|
r := newGetRequest("artist=Rick+Astley", "title=Never+Gonna+Give+You+Up")
|
|
|
|
mockRepo.SetData(model.MediaFiles{
|
|
|
|
{
|
|
|
|
ID: "1",
|
|
|
|
Artist: "Rick Astley",
|
|
|
|
Title: "Never Gonna Give You Up",
|
|
|
|
Lyrics: "[00:18.80]We're no strangers to love\n[00:22.80]You know the rules and so do I",
|
|
|
|
},
|
|
|
|
})
|
2022-11-21 18:57:56 +01:00
|
|
|
response, err := router.GetLyrics(r)
|
2021-10-19 22:33:06 +02:00
|
|
|
if err != nil {
|
|
|
|
log.Error("You're missing something.", err)
|
|
|
|
}
|
|
|
|
Expect(err).To(BeNil())
|
|
|
|
Expect(response.Lyrics.Artist).To(Equal("Rick Astley"))
|
|
|
|
Expect(response.Lyrics.Title).To(Equal("Never Gonna Give You Up"))
|
|
|
|
Expect(response.Lyrics.Value).To(Equal("We're no strangers to love\nYou know the rules and so do I"))
|
|
|
|
})
|
|
|
|
It("should return empty subsonic response if the record corresponding to the given artist & title is not found", func() {
|
|
|
|
r := newGetRequest("artist=Dheeraj", "title=Rinkiya+Ke+Papa")
|
|
|
|
mockRepo.SetData(model.MediaFiles{})
|
2022-11-21 18:57:56 +01:00
|
|
|
response, err := router.GetLyrics(r)
|
2021-10-19 22:33:06 +02:00
|
|
|
if err != nil {
|
|
|
|
log.Error("You're missing something.", err)
|
|
|
|
}
|
|
|
|
Expect(err).To(BeNil())
|
|
|
|
Expect(response.Lyrics.Artist).To(Equal(""))
|
|
|
|
Expect(response.Lyrics.Title).To(Equal(""))
|
|
|
|
Expect(response.Lyrics.Value).To(Equal(""))
|
|
|
|
|
|
|
|
})
|
|
|
|
})
|
2020-01-10 03:58:03 +01:00
|
|
|
})
|
2020-07-31 15:31:19 +02:00
|
|
|
|
|
|
|
type fakeArtwork struct {
|
2023-02-01 00:22:49 +01:00
|
|
|
artwork.Artwork
|
2020-07-31 15:31:19 +02:00
|
|
|
data string
|
|
|
|
err error
|
|
|
|
recvId string
|
|
|
|
recvSize int
|
|
|
|
}
|
|
|
|
|
2023-02-01 00:22:49 +01:00
|
|
|
func (c *fakeArtwork) GetOrPlaceholder(_ context.Context, id string, size int) (io.ReadCloser, time.Time, error) {
|
2020-07-31 15:31:19 +02:00
|
|
|
if c.err != nil {
|
2022-12-27 20:30:00 +01:00
|
|
|
return nil, time.Time{}, c.err
|
2020-07-31 15:31:19 +02:00
|
|
|
}
|
|
|
|
c.recvId = id
|
|
|
|
c.recvSize = size
|
2022-12-27 20:30:00 +01:00
|
|
|
return io.NopCloser(bytes.NewReader([]byte(c.data))), time.Time{}, nil
|
2020-07-31 15:31:19 +02:00
|
|
|
}
|
2021-10-19 22:33:06 +02:00
|
|
|
|
|
|
|
var _ = Describe("isSynced", func() {
|
|
|
|
It("returns false if lyrics contain no timestamps", func() {
|
|
|
|
Expect(isSynced("Just in case my car goes off the highway")).To(Equal(false))
|
|
|
|
Expect(isSynced("[02.50] Just in case my car goes off the highway")).To(Equal(false))
|
|
|
|
})
|
|
|
|
It("returns false if lyrics is an empty string", func() {
|
|
|
|
Expect(isSynced("")).To(Equal(false))
|
|
|
|
})
|
|
|
|
It("returns true if lyrics contain timestamps", func() {
|
|
|
|
Expect(isSynced(`NF Real Music
|
2022-11-21 18:57:56 +01:00
|
|
|
[00:00] First line
|
2021-10-19 22:33:06 +02:00
|
|
|
[00:00.85] JUST LIKE YOU
|
|
|
|
[00:00.85] Just in case my car goes off the highway`)).To(Equal(true))
|
|
|
|
Expect(isSynced("[04:02:50.85] Never gonna give you up")).To(Equal(true))
|
|
|
|
Expect(isSynced("[02:50.85] Never gonna give you up")).To(Equal(true))
|
|
|
|
Expect(isSynced("[02:50] Never gonna give you up")).To(Equal(true))
|
|
|
|
})
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
type mockedMediaFile struct {
|
|
|
|
model.MediaFileRepository
|
|
|
|
data model.MediaFiles
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *mockedMediaFile) SetData(mfs model.MediaFiles) {
|
|
|
|
m.data = mfs
|
|
|
|
}
|
|
|
|
|
2022-11-21 18:57:56 +01:00
|
|
|
func (m *mockedMediaFile) GetAll(...model.QueryOptions) (model.MediaFiles, error) {
|
2021-10-19 22:33:06 +02:00
|
|
|
return m.data, nil
|
|
|
|
}
|