diff --git a/adapters/listenbrainz/agent.go b/adapters/listenbrainz/agent.go index a1cbb1b1c..5eaa30334 100644 --- a/adapters/listenbrainz/agent.go +++ b/adapters/listenbrainz/agent.go @@ -141,9 +141,18 @@ func (l *listenBrainzAgent) GetArtistTopSongs(ctx context.Context, id, artistNam res := make([]agents.Song, len(resp)) for i, t := range resp { + mbid := "" + if len(t.ArtistMBIDs) > 0 { + mbid = t.ArtistMBIDs[0] + } + res[i] = agents.Song{ - Name: t.RecordingName, - MBID: t.RecordingMbid, + Album: t.ReleaseName, + AlbumMBID: t.ReleaseMBID, + Artist: t.ArtistName, + ArtistMBID: mbid, + Name: t.RecordingName, + MBID: t.RecordingMbid, } } return res, nil diff --git a/adapters/listenbrainz/agent_test.go b/adapters/listenbrainz/agent_test.go index dc155dfec..1f50da999 100644 --- a/adapters/listenbrainz/agent_test.go +++ b/adapters/listenbrainz/agent_test.go @@ -11,6 +11,7 @@ import ( "time" "github.com/navidrome/navidrome/consts" + "github.com/navidrome/navidrome/core/agents" "github.com/navidrome/navidrome/core/scrobbler" "github.com/navidrome/navidrome/model" "github.com/navidrome/navidrome/tests" @@ -200,7 +201,7 @@ var _ = Describe("listenBrainzAgent", func() { Expect(httpClient.SavedRequest.URL.Query().Get("artist_mbids")).To(Equal("7c2cc610-f998-43ef-a08f-dae3344b8973")) }) - It("returns error when fListenBrainz returns an error", func() { + It("returns error when ListenBrainz returns an error", func() { httpClient.Res = http.Response{ Body: io.NopCloser(bytes.NewBufferString(`{"code": 400,"error": "artist mbid 1 is not valid."}`)), StatusCode: 400, @@ -211,4 +212,79 @@ var _ = Describe("listenBrainzAgent", func() { Expect(httpClient.SavedRequest.URL.Query().Get("artist_mbids")).To(Equal("7c2cc610-f998-43ef-a08f-dae3344b8973")) }) }) + + Describe("GetTopSongs", func() { + var agent *listenBrainzAgent + var httpClient *tests.FakeHttpClient + BeforeEach(func() { + httpClient = &tests.FakeHttpClient{} + client := newClient("BASE_URL", httpClient) + agent = listenBrainzConstructor(ds) + agent.client = client + }) + + It("returns error when fetch calls", func() { + httpClient.Err = errors.New("error") + _, err := agent.GetArtistTopSongs(ctx, "", "", "d2a92ee2-27ce-4e71-bfc5-12e34fe8ef56", 1) + Expect(err).To(HaveOccurred()) + Expect(httpClient.RequestCount).To(Equal(1)) + Expect(httpClient.SavedRequest.URL.Path).To(Equal("BASE_URL/popularity/top-recordings-for-artist/d2a92ee2-27ce-4e71-bfc5-12e34fe8ef56")) + }) + + It("returns an error on listenbrainz error", func() { + httpClient.Res = http.Response{ + Body: io.NopCloser(bytes.NewBufferString(`{"code":400,"error":"artist_mbid: '1' is not a valid uuid"}`)), + StatusCode: 400, + } + _, err := agent.GetArtistTopSongs(ctx, "", "", "1", 1) + Expect(err).To(HaveOccurred()) + Expect(httpClient.RequestCount).To(Equal(1)) + Expect(httpClient.SavedRequest.URL.Path).To(Equal("BASE_URL/popularity/top-recordings-for-artist/1")) + }) + + It("returns all tracks when asked", func() { + f, _ := os.Open("tests/fixtures/listenbrainz.popularity.json") + httpClient.Res = http.Response{Body: f, StatusCode: 200} + data, err := agent.GetArtistTopSongs(ctx, "", "", "d2a92ee2-27ce-4e71-bfc5-12e34fe8ef56", 2) + Expect(err).ToNot(HaveOccurred()) + Expect(data).To(Equal([]agents.Song{ + { + ID: "", + Name: "world.execute(me);", + MBID: "9980309d-3480-4e7e-89ce-fce971a452be", + Artist: "Mili", + ArtistMBID: "d2a92ee2-27ce-4e71-bfc5-12e34fe8ef56", + Album: "Miracle Milk", + AlbumMBID: "38a8f6e1-0e34-4418-a89d-78240a367408", + }, + { + ID: "", + Name: "String Theocracy", + MBID: "afa2c83d-b17f-4029-b9da-790ea9250cf9", + Artist: "Mili", + ArtistMBID: "d2a92ee2-27ce-4e71-bfc5-12e34fe8ef56", + Album: "String Theocracy", + AlbumMBID: "d79a38e3-7016-4f39-a31a-f495ce914b8e", + }, + })) + }) + + It("returns only one track when prompted", func() { + f, _ := os.Open("tests/fixtures/listenbrainz.popularity.json") + httpClient.Res = http.Response{Body: f, StatusCode: 200} + data, err := agent.GetArtistTopSongs(ctx, "", "", "d2a92ee2-27ce-4e71-bfc5-12e34fe8ef56", 1) + Expect(err).ToNot(HaveOccurred()) + Expect(data).To(Equal([]agents.Song{ + { + ID: "", + Name: "world.execute(me);", + MBID: "9980309d-3480-4e7e-89ce-fce971a452be", + Artist: "Mili", + ArtistMBID: "d2a92ee2-27ce-4e71-bfc5-12e34fe8ef56", + Album: "Miracle Milk", + AlbumMBID: "38a8f6e1-0e34-4418-a89d-78240a367408", + }, + })) + }) + }) }) diff --git a/adapters/listenbrainz/client.go b/adapters/listenbrainz/client.go index 1ecabf6b7..9d64422c3 100644 --- a/adapters/listenbrainz/client.go +++ b/adapters/listenbrainz/client.go @@ -253,8 +253,12 @@ func (c *client) getArtistUrl(ctx context.Context, mbid string) (string, error) } type trackInfo struct { - RecordingName string `json:"recording_name"` - RecordingMbid string `json:"recording_mbid"` + ArtistName string `json:"artist_name"` + ArtistMBIDs []string `json:"artist_mbids"` + RecordingName string `json:"recording_name"` + RecordingMbid string `json:"recording_mbid"` + ReleaseName string `json:"release_name"` + ReleaseMBID string `json:"release_mbid"` } func (c *client) getArtistTopSongs(ctx context.Context, mbid string, count int) ([]trackInfo, error) { diff --git a/adapters/listenbrainz/client_test.go b/adapters/listenbrainz/client_test.go index 478682cfc..c3597a49b 100644 --- a/adapters/listenbrainz/client_test.go +++ b/adapters/listenbrainz/client_test.go @@ -195,15 +195,26 @@ var _ = Describe("client", func() { It("It returns all tracks when given the opportunity", func() { f, _ := os.Open("tests/fixtures/listenbrainz.popularity.json") - httpClient.Res = http.Response{ - Body: f, - StatusCode: 200, - } + httpClient.Res = http.Response{Body: f, StatusCode: 200} data, err := client.getArtistTopSongs(context.Background(), "d2a92ee2-27ce-4e71-bfc5-12e34fe8ef56", 5) Expect(err).ToNot(HaveOccurred()) Expect(data).To(Equal([]trackInfo{ - {RecordingName: "world.execute(me);", RecordingMbid: "9980309d-3480-4e7e-89ce-fce971a452be"}, - {RecordingName: "String Theocracy", RecordingMbid: "afa2c83d-b17f-4029-b9da-790ea9250cf9"}, + { + ArtistName: "Mili", + ArtistMBIDs: []string{"d2a92ee2-27ce-4e71-bfc5-12e34fe8ef56"}, + RecordingName: "world.execute(me);", + RecordingMbid: "9980309d-3480-4e7e-89ce-fce971a452be", + ReleaseName: "Miracle Milk", + ReleaseMBID: "38a8f6e1-0e34-4418-a89d-78240a367408", + }, + { + ArtistName: "Mili", + ArtistMBIDs: []string{"d2a92ee2-27ce-4e71-bfc5-12e34fe8ef56"}, + RecordingName: "String Theocracy", + RecordingMbid: "afa2c83d-b17f-4029-b9da-790ea9250cf9", + ReleaseName: "String Theocracy", + ReleaseMBID: "d79a38e3-7016-4f39-a31a-f495ce914b8e", + }, })) Expect(httpClient.SavedRequest.Method).To(Equal(http.MethodGet)) Expect(httpClient.SavedRequest.URL.String()).To(Equal(baseUrl + "d2a92ee2-27ce-4e71-bfc5-12e34fe8ef56")) @@ -212,14 +223,18 @@ var _ = Describe("client", func() { It("It returns a subset of tracks when allowed", func() { f, _ := os.Open("tests/fixtures/listenbrainz.popularity.json") - httpClient.Res = http.Response{ - Body: f, - StatusCode: 200, - } + httpClient.Res = http.Response{Body: f, StatusCode: 200} data, err := client.getArtistTopSongs(context.Background(), "d2a92ee2-27ce-4e71-bfc5-12e34fe8ef56", 1) Expect(err).ToNot(HaveOccurred()) Expect(data).To(Equal([]trackInfo{ - {RecordingName: "world.execute(me);", RecordingMbid: "9980309d-3480-4e7e-89ce-fce971a452be"}, + { + ArtistName: "Mili", + ArtistMBIDs: []string{"d2a92ee2-27ce-4e71-bfc5-12e34fe8ef56"}, + RecordingName: "world.execute(me);", + RecordingMbid: "9980309d-3480-4e7e-89ce-fce971a452be", + ReleaseName: "Miracle Milk", + ReleaseMBID: "38a8f6e1-0e34-4418-a89d-78240a367408", + }, })) Expect(httpClient.SavedRequest.Method).To(Equal(http.MethodGet)) Expect(httpClient.SavedRequest.URL.String()).To(Equal(baseUrl + "d2a92ee2-27ce-4e71-bfc5-12e34fe8ef56"))