navidrome/model/album_test.go
Deluan e100c48102 fix(artwork): address blurhash review findings
- force recompute on image-cache miss, so in-place cover/sidecar swaps and
  agent image updates refresh the stored hash even when no entity row moved
- exclude external_info_updated_at from the artwork version: agent TTL
  refreshes bump it with an unchanged image, churning Finamp's cover cache
- lazy-start the worker goroutine and bound each computation with a 30s
  timeout; remember no-result entities per version to avoid re-decoding
  placeholders on every serve
- error (instead of silently skipping) on unknown artwork kinds in persist
2026-07-16 21:52:28 -04:00

72 lines
2.4 KiB
Go

package model_test
import (
"encoding/json"
"time"
"github.com/navidrome/navidrome/conf"
"github.com/navidrome/navidrome/conf/configtest"
. "github.com/navidrome/navidrome/model"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
var _ = Describe("Album", func() {
BeforeEach(func() {
DeferCleanup(configtest.SetupConfig())
})
DescribeTable("FullName",
func(enabled bool, tags Tags, expected string) {
conf.Server.Subsonic.AppendAlbumVersion = enabled
a := Album{Name: "Album", Tags: tags}
Expect(a.FullName()).To(Equal(expected))
},
Entry("appends version when enabled and tag is present", true, Tags{TagAlbumVersion: []string{"Remastered"}}, "Album (Remastered)"),
Entry("returns just name when disabled", false, Tags{TagAlbumVersion: []string{"Remastered"}}, "Album"),
Entry("returns just name when tag is absent", true, Tags{}, "Album"),
Entry("returns just name when tag is an empty slice", true, Tags{TagAlbumVersion: []string{}}, "Album"),
)
})
var _ = Describe("Albums", func() {
var albums Albums
Context("JSON Marshalling", func() {
When("we have a valid Albums object", func() {
BeforeEach(func() {
albums = Albums{
{ID: "1", AlbumArtist: "Artist", AlbumArtistID: "11", SortAlbumArtistName: "SortAlbumArtistName", OrderAlbumArtistName: "OrderAlbumArtistName"},
{ID: "2", AlbumArtist: "Artist", AlbumArtistID: "11", SortAlbumArtistName: "SortAlbumArtistName", OrderAlbumArtistName: "OrderAlbumArtistName"},
}
})
It("marshals correctly", func() {
data, err := json.Marshal(albums)
Expect(err).To(BeNil())
var albums2 Albums
err = json.Unmarshal(data, &albums2)
Expect(err).To(BeNil())
Expect(albums2).To(Equal(albums))
})
})
})
})
var _ = Describe("Album.ArtworkUpdatedAt", func() {
base := time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC)
later := base.Add(24 * time.Hour)
latest := base.Add(48 * time.Hour)
It("returns UpdatedAt when it is the newest", func() {
al := Album{UpdatedAt: later, ImportedAt: base}
Expect(al.ArtworkUpdatedAt()).To(Equal(later))
})
It("returns ImportedAt when it is the newest", func() {
al := Album{UpdatedAt: base, ImportedAt: later}
Expect(al.ArtworkUpdatedAt()).To(Equal(later))
})
It("ignores ExternalInfoUpdatedAt (agent TTL refreshes bump it without an image change)", func() {
al := Album{UpdatedAt: base, ImportedAt: later, ExternalInfoUpdatedAt: &latest}
Expect(al.ArtworkUpdatedAt()).To(Equal(later))
})
})