From 271eaf934cf5d3c97f29058536c424238a2e5fa0 Mon Sep 17 00:00:00 2001 From: Deluan Date: Fri, 19 Jun 2026 17:26:31 -0400 Subject: [PATCH] test(lyrics): cover legacy getLyrics across formats and sources MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Expand the legacy getLyrics e2e coverage from a single embedded-plain case to a table over all six fixtures: embedded LRC/plain/TTML and sidecar LRC/SRT/YAML. Each case asserts the v1 plain-text fallback contract — the structured lyric is flattened to LRC-style plain text with no timing markup leaking through (no LRC brackets, SRT arrows, or XML tags), regardless of the source format or whether it is embedded or a sidecar file. This pins the behavior that synced TTML/SRT/ YAML formats degrade gracefully to plain text on the legacy endpoint. --- server/e2e/subsonic_lyrics_test.go | 35 ++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/server/e2e/subsonic_lyrics_test.go b/server/e2e/subsonic_lyrics_test.go index 8a1e207e6..ca08ae441 100644 --- a/server/e2e/subsonic_lyrics_test.go +++ b/server/e2e/subsonic_lyrics_test.go @@ -50,12 +50,33 @@ var _ = Describe("Lyrics endpoints", func() { }) Describe("getLyrics (legacy artist/title)", func() { - It("returns the main lyric as plain text for an embedded match", func() { - resp := doReq("getLyrics", "artist", "Lyric Tester", "title", "Embedded Plain") - Expect(resp.Status).To(Equal("ok")) - Expect(resp.Lyrics).ToNot(BeNil()) - Expect(resp.Lyrics.Value).To(ContainSubstring("plain embedded line one")) - Expect(resp.Lyrics.Value).To(ContainSubstring("plain embedded line two")) - }) + // The legacy endpoint flattens the main lyric to plain text: it emits each + // line's Value joined by newlines, dropping all timing/markup. This is the + // v1 contract — synced structured formats (LRC/TTML/SRT/YAML) all "fall + // back" to LRC-style plain text here. + DescribeTable("returns the main lyric as plain text across formats and sources", + func(title string, wantLines []string) { + resp := doReq("getLyrics", "artist", "Lyric Tester", "title", title) + Expect(resp.Status).To(Equal("ok")) + Expect(resp.Lyrics).ToNot(BeNil()) + Expect(resp.Lyrics.Artist).To(Equal("Lyric Tester")) + Expect(resp.Lyrics.Title).To(Equal(title)) + for _, line := range wantLines { + Expect(resp.Lyrics.Value).To(ContainSubstring(line)) + } + // v1 fallback: no timing markup leaks into the plain-text value, + // regardless of the source format (LRC brackets, SRT arrows, XML + // tags). The structured content is reduced to LRC-style plain text. + Expect(resp.Lyrics.Value).ToNot(ContainSubstring("[")) + Expect(resp.Lyrics.Value).ToNot(ContainSubstring("-->")) + Expect(resp.Lyrics.Value).ToNot(ContainSubstring("<")) + }, + Entry("embedded synced LRC", "Embedded Synced LRC", []string{"embedded lrc line one", "embedded lrc line two"}), + Entry("embedded plain text", "Embedded Plain", []string{"plain embedded line one", "plain embedded line two"}), + Entry("embedded TTML", "Embedded TTML", []string{"embedded ttml line"}), + Entry("LRC sidecar", "Sidecar LRC", []string{"sidecar lrc line"}), + Entry("SRT sidecar", "Sidecar SRT", []string{"sidecar srt line"}), + Entry("YAML sidecar", "Sidecar YAML", []string{"sidecar yaml line"}), + ) }) })