From 03f43c1f6010e3adbff069e7c68ab7f8ff55f18b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Wallstr=C3=B6m?= Date: Sun, 15 Mar 2026 01:35:12 +0100 Subject: [PATCH] Handle folder IDs in getMusicDirectory per Subsonic spec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Patrik Wallström --- server/subsonic/browsing.go | 2 ++ server/subsonic/browsing_test.go | 46 ++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/server/subsonic/browsing.go b/server/subsonic/browsing.go index 397e98cec..bb051f952 100644 --- a/server/subsonic/browsing.go +++ b/server/subsonic/browsing.go @@ -143,6 +143,8 @@ func (api *Router) GetMusicDirectory(r *http.Request) (*responses.Subsonic, erro var dir *responses.Directory switch v := entity.(type) { + case *model.Folder: + dir, err = api.buildFolderDirectory(ctx, v) case *model.Artist: dir, err = api.buildArtistDirectory(ctx, v) case *model.Album: diff --git a/server/subsonic/browsing_test.go b/server/subsonic/browsing_test.go index 2109faa69..c8ae92290 100644 --- a/server/subsonic/browsing_test.go +++ b/server/subsonic/browsing_test.go @@ -143,6 +143,52 @@ var _ = Describe("Browsing", func() { }) }) + Describe("GetMusicDirectory with folder ID", func() { + It("returns directory for a valid folder ID", func() { + ctx = contextWithUser(ctx, "user-id", 1) + folder := model.Folder{ID: "folder-1", ParentID: "root-1", Name: "Rock"} + ds.Folder(ctx).(*tests.MockFolderRepo).SetData([]model.Folder{folder}) + + r := httptest.NewRequest("GET", "/rest/getMusicDirectory?id=folder-1", nil) + r = r.WithContext(ctx) + + response, err := api.GetMusicDirectory(r) + Expect(err).ToNot(HaveOccurred()) + Expect(response.Directory).ToNot(BeNil()) + Expect(response.Directory.Id).To(Equal("folder-1")) + Expect(response.Directory.Name).To(Equal("Rock")) + Expect(response.Directory.Parent).To(Equal("root-1")) + }) + + It("returns error for unknown ID", func() { + ctx = contextWithUser(ctx, "user-id", 1) + + r := httptest.NewRequest("GET", "/rest/getMusicDirectory?id=nonexistent", nil) + r = r.WithContext(ctx) + + response, err := api.GetMusicDirectory(r) + Expect(err).To(HaveOccurred()) + Expect(response).To(BeNil()) + }) + + It("includes child folders as IsDir=true entries in the directory", func() { + ctx = contextWithUser(ctx, "user-id", 1) + folder := model.Folder{ID: "folder-1", ParentID: "", Name: "Music"} + child := model.Folder{ID: "folder-2", ParentID: "folder-1", Name: "Jazz"} + ds.Folder(ctx).(*tests.MockFolderRepo).SetData([]model.Folder{folder, child}) + + r := httptest.NewRequest("GET", "/rest/getMusicDirectory?id=folder-1", nil) + r = r.WithContext(ctx) + + response, err := api.GetMusicDirectory(r) + Expect(err).ToNot(HaveOccurred()) + // The mock returns all folders; verify child-2 is present and IsDir + Expect(response.Directory.Child).To(ContainElement( + And(HaveField("Id", "folder-2"), HaveField("IsDir", true)), + )) + }) + }) + Describe("GetIndexes", func() { It("should validate user access to the specified musicFolderId", func() { // Create mock user with access to library 1 only