diff --git a/core/lyrics/lyrics_test.go b/core/lyrics/lyrics_test.go index ec101922c..6baacbe71 100644 --- a/core/lyrics/lyrics_test.go +++ b/core/lyrics/lyrics_test.go @@ -225,7 +225,7 @@ var _ = Describe("Lyrics", func() { })) }) - It("falls through generic YAML sidecars that are not Lyricsfile documents", func() { + It("returns a non-Lyricsfile YAML sidecar as plain text, shadowing lower-priority sources", func() { dir, err := os.MkdirTemp("", "lyrics-yaml-fallback-*") Expect(err).ToNot(HaveOccurred()) DeferCleanup(func() { @@ -242,10 +242,14 @@ var _ = Describe("Lyrics", func() { Path: "song.mp3", }) + // ParseLyrics falls back to plain text for any suffix when the content + // doesn't match the structured format, so the .yaml hit is non-empty and + // shadows the lower-priority .lrc entirely. Expect(err).To(BeNil()) Expect(list).To(HaveLen(1)) + Expect(list[0].Synced).To(BeFalse()) Expect(list[0].Line).To(Equal([]model.Line{ - {Start: new(int64(1000)), Value: "Fallback line"}, + {Value: "title: not lyricsfile"}, })) }) diff --git a/server/subsonic/api_suite_test.go b/server/subsonic/api_suite_test.go index a83f2f0eb..485daca58 100644 --- a/server/subsonic/api_suite_test.go +++ b/server/subsonic/api_suite_test.go @@ -1,9 +1,13 @@ package subsonic import ( + "io/fs" "testing" + "github.com/navidrome/navidrome/consts" + "github.com/navidrome/navidrome/core/storage/local" "github.com/navidrome/navidrome/log" + "github.com/navidrome/navidrome/model/metadata" "github.com/navidrome/navidrome/tests" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -15,3 +19,16 @@ func TestSubsonicApi(t *testing.T) { RegisterFailHandler(Fail) RunSpecs(t, "Subsonic API Suite") } + +// newLocalStorage fatals if the default extractor is not registered. +// Register a no-op so storage.For works in sidecar-lyrics tests. +var _ = BeforeSuite(func() { + local.RegisterExtractor(consts.DefaultScannerExtractor, func(fs.FS, string) local.Extractor { + return &subsonicNoopExtractor{} + }) +}) + +type subsonicNoopExtractor struct{} + +func (e *subsonicNoopExtractor) Parse(_ ...string) (map[string]metadata.Info, error) { return nil, nil } +func (e *subsonicNoopExtractor) Version() string { return "noop" } diff --git a/server/subsonic/lyrics_test.go b/server/subsonic/lyrics_test.go index fd9a3f3f3..f4ba6208a 100644 --- a/server/subsonic/lyrics_test.go +++ b/server/subsonic/lyrics_test.go @@ -2,6 +2,7 @@ package subsonic import ( "encoding/json" + "path/filepath" "github.com/navidrome/navidrome/conf" "github.com/navidrome/navidrome/conf/configtest" @@ -202,13 +203,16 @@ var _ = Describe("GetLyricsBySongId", func() { conf.Server.LyricsPriority = ".ttml,embedded" r := newGetRequest("id=1") + fixturesDir, err := filepath.Abs("tests/fixtures") + Expect(err).ToNot(HaveOccurred()) mockRepo.SetData(model.MediaFiles{ { - ID: "1", - Path: "tests/fixtures/test.mp3", - Artist: "Rick Astley", - Title: "Never Gonna Give You Up", - Lyrics: "[]", + ID: "1", + LibraryPath: fixturesDir, + Path: "test.mp3", + Artist: "Rick Astley", + Title: "Never Gonna Give You Up", + Lyrics: "[]", }, }) @@ -255,13 +259,16 @@ var _ = Describe("GetLyricsBySongId", func() { conf.Server.LyricsPriority = ".ttml,embedded" r := newGetRequest("id=1&enhanced=true") + fixturesDir, err := filepath.Abs("tests/fixtures") + Expect(err).ToNot(HaveOccurred()) mockRepo.SetData(model.MediaFiles{ { - ID: "1", - Path: "tests/fixtures/test-metadata.mp3", - Artist: "Rick Astley", - Title: "Never Gonna Give You Up", - Lyrics: "[]", + ID: "1", + LibraryPath: fixturesDir, + Path: "test-metadata.mp3", + Artist: "Rick Astley", + Title: "Never Gonna Give You Up", + Lyrics: "[]", }, }) diff --git a/server/subsonic/media_retrieval_test.go b/server/subsonic/media_retrieval_test.go index f8b21c700..228427d5a 100644 --- a/server/subsonic/media_retrieval_test.go +++ b/server/subsonic/media_retrieval_test.go @@ -8,6 +8,7 @@ import ( "errors" "io" "net/http/httptest" + "path/filepath" "slices" "time" @@ -164,12 +165,15 @@ var _ = Describe("MediaRetrievalController", func() { }) It("should return lyric file when finding mediafile with no embedded lyrics but present on filesystem", func() { r := newGetRequest("artist=Rick+Astley", "title=Never+Gonna+Give+You+Up") + fixturesDir, err := filepath.Abs("tests/fixtures") + Expect(err).ToNot(HaveOccurred()) mockRepo.SetData(model.MediaFiles{ { - Path: "tests/fixtures/test.mp3", - ID: "1", - Artist: "Rick Astley", - Title: "Never Gonna Give You Up", + LibraryPath: fixturesDir, + Path: "test.mp3", + ID: "1", + Artist: "Rick Astley", + Title: "Never Gonna Give You Up", }, }) response, err := router.GetLyrics(r)