From eb5ecabc5ac9635a864f631947c2f8da3e09fed7 Mon Sep 17 00:00:00 2001 From: Deluan Date: Fri, 17 Jul 2026 19:35:13 -0400 Subject: [PATCH] test(artwork): characterize mtime-preserved cover swap staleness (pending) A cover replaced in place without a mtime change is not re-hashed today: the freshness guard skips recompute when no timestamp moved, so the stored blurhash (and the client's cover cache keyed by it) stays stale. Marked pending until the served-bytes tee lands, which recomputes from the exact bytes served. --- core/artwork/e2e/blurhash_test.go | 35 +++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/core/artwork/e2e/blurhash_test.go b/core/artwork/e2e/blurhash_test.go index 2dbf8da00..148a3ff56 100644 --- a/core/artwork/e2e/blurhash_test.go +++ b/core/artwork/e2e/blurhash_test.go @@ -120,6 +120,41 @@ var _ = Describe("BlurHash", func() { }, "10s", "100ms").Should(Succeed()) }) + PIt("recomputes when cover bytes change under a preserved mtime (cache disabled)", func() { + cover := realPNG("orig-bytes") + fixed := time.Date(2026, 1, 1, 0, 0, 0, 0, time.UTC) + cover.ModTime = fixed + setLayout(fstest.MapFS{ + "Artist/Album/01 - Song.mp3": trackFile(1, "Song"), + "Artist/Album/cover.png": cover, + }) + scan() + al := firstAlbum() + readArtwork(al.CoverArtID()) + var firstHash string + Eventually(func(g Gomega) { + updated, err := ds.Album(ctx).Get(al.ID) + g.Expect(err).ToNot(HaveOccurred()) + g.Expect(updated.BlurHash).ToNot(BeEmpty()) + firstHash = updated.BlurHash + }, "10s", "100ms").Should(Succeed()) + + // Replace the bytes but keep the SAME mtime and do NOT rescan: only the served bytes change. + swapped := realPNG("swapped-bytes") + swapped.ModTime = fixed + setLayout(fstest.MapFS{ + "Artist/Album/01 - Song.mp3": trackFile(1, "Song"), + "Artist/Album/cover.png": swapped, + }) + readArtwork(al.CoverArtID()) + + Eventually(func(g Gomega) { + updated, err := ds.Album(ctx).Get(al.ID) + g.Expect(err).ToNot(HaveOccurred()) + g.Expect(updated.BlurHash).ToNot(Equal(firstHash)) + }, "10s", "100ms").Should(Succeed()) + }) + It("does not persist a blurhash when the served image cannot be decoded", func() { setLayout(fstest.MapFS{ "Artist/Album/01 - Song.mp3": trackFile(1, "Song"),