fix(db): Include items with no annotation for starred=false, handle has_rating=false (#4921)

* fix(db): Include items with no annotation for starred=false, handle has_rating=false

* hardcode starred instead

* test: ensure albums and artists without annotations are included in starred and has_rating filters

Signed-off-by: Deluan <deluan@navidrome.org>

* refactor: replace starred and has_rating filters with annotationBoolFilter for consistency

Signed-off-by: Deluan <deluan@navidrome.org>

* fix: update annotationBoolFilter to handle boolean values correctly in SQL expressions

Signed-off-by: Deluan <deluan@navidrome.org>

---------

Signed-off-by: Deluan <deluan@navidrome.org>
Co-authored-by: Deluan <deluan@navidrome.org>
This commit is contained in:
Kendall Garner
2026-01-21 10:45:17 -08:00
committed by GitHub
parent 6fce30c133
commit b1b488be77
8 changed files with 342 additions and 8 deletions
+49
View File
@@ -5,6 +5,7 @@ import (
"encoding/json"
"github.com/Masterminds/squirrel"
"github.com/deluan/rest"
"github.com/navidrome/navidrome/conf"
"github.com/navidrome/navidrome/conf/configtest"
"github.com/navidrome/navidrome/model"
@@ -386,6 +387,54 @@ var _ = Describe("ArtistRepository", func() {
})
})
Describe("Filters", func() {
var artistWithoutAnnotation model.Artist
BeforeEach(func() {
// Create artist without any annotation
artistWithoutAnnotation = model.Artist{ID: "no-annotation-artist", Name: "No Annotation Artist"}
err := createArtistWithLibrary(repo, &artistWithoutAnnotation, 1)
Expect(err).ToNot(HaveOccurred())
})
AfterEach(func() {
if raw, ok := repo.(*artistRepository); ok {
_, _ = raw.executeSQL(squirrel.Delete(raw.tableName).Where(squirrel.Eq{"id": artistWithoutAnnotation.ID}))
}
})
Describe("starred", func() {
It("false includes items without annotations", func() {
res, err := repo.(model.ResourceRepository).ReadAll(rest.QueryOptions{
Filters: map[string]any{"starred": "false"},
})
Expect(err).ToNot(HaveOccurred())
artists := res.(model.Artists)
var found bool
for _, a := range artists {
if a.ID == artistWithoutAnnotation.ID {
found = true
break
}
}
Expect(found).To(BeTrue(), "Artist without annotation should be included in starred=false filter")
})
It("true excludes items without annotations", func() {
res, err := repo.(model.ResourceRepository).ReadAll(rest.QueryOptions{
Filters: map[string]any{"starred": "true"},
})
Expect(err).ToNot(HaveOccurred())
artists := res.(model.Artists)
for _, a := range artists {
Expect(a.ID).ToNot(Equal(artistWithoutAnnotation.ID))
}
})
})
})
Describe("MBID and Text Search", func() {
var lib2 model.Library
var lr model.LibraryRepository