Files
silo-server/internal/audiobooks/service_test.go
339ed20074 fix(audiobooks): improve poster enrichment throughput (#94)
* fix(audiobooks): improve poster enrichment throughput

* fix(audiobooks): enable ABS compat by default

* chore(audiobooks): remove stale feature flag setting

* fix(audiobooks): validate scoped scan roots

---------

Co-authored-by: rxwatcher <rxwatcher@users.noreply.github.com>
2026-06-08 18:17:08 -04:00

131 lines
3.6 KiB
Go

package audiobooks
import (
"context"
"errors"
"reflect"
"strings"
"testing"
"unsafe"
"github.com/Silo-Server/silo-server/internal/audiobooks/abs"
"github.com/Silo-Server/silo-server/internal/catalog"
"github.com/Silo-Server/silo-server/internal/scanner"
)
type fakeSettingsReader struct {
value string
err error
}
func (f *fakeSettingsReader) GetString(_ context.Context, key string) (string, error) {
if key != "audiobookshelf_compat.enabled" {
return "", errors.New("unexpected key: " + key)
}
return f.value, f.err
}
func TestServiceABSCompatEnabledReadsFlag(t *testing.T) {
cases := []struct {
name string
stored string
want bool
}{
{"flag true", "true", true},
{"flag false", "false", false},
{"flag empty defaults false", "", false},
{"flag garbage defaults false", "yes-please", false},
}
for _, tc := range cases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
svc := New(&fakeSettingsReader{value: tc.stored})
got, err := svc.ABSCompatEnabled(context.Background())
if err != nil {
t.Fatalf("ABSCompatEnabled returned error: %v", err)
}
if got != tc.want {
t.Fatalf("ABSCompatEnabled = %v, want %v", got, tc.want)
}
})
}
}
func TestServiceABSCompatEnabledPropagatesError(t *testing.T) {
wantErr := errors.New("db down")
svc := New(&fakeSettingsReader{err: wantErr})
_, err := svc.ABSCompatEnabled(context.Background())
if !errors.Is(err, wantErr) {
t.Fatalf("ABSCompatEnabled error = %v, want %v wrapped", err, wantErr)
}
}
func TestServiceABSCompatEnabledNilReceiverReturnsFalse(t *testing.T) {
var svc *Service
got, err := svc.ABSCompatEnabled(context.Background())
if err != nil {
t.Fatalf("ABSCompatEnabled returned error: %v", err)
}
if got {
t.Fatal("ABSCompatEnabled = true, want false")
}
}
func TestServiceABSCompatEnabledNilSettingsReturnsFalse(t *testing.T) {
svc := New(nil)
got, err := svc.ABSCompatEnabled(context.Background())
if err != nil {
t.Fatalf("ABSCompatEnabled returned error: %v", err)
}
if got {
t.Fatal("ABSCompatEnabled = true, want false")
}
}
func TestBuildABSHandlerCoverResolverUsesPosterVariant(t *testing.T) {
resolver := &recordingImageResolver{}
detail := &catalog.DetailService{}
detail.SetImageResolver(resolver)
handler := New(nil).BuildABSHandler(ABSHandlerDeps{
Items: &catalog.ItemRepository{},
Files: &scanner.FileRepository{},
Detail: detail,
})
coverResolver := absCoverResolverForTest(t, handler)
got := coverResolver(context.Background(), "local/audiobooks/book-1/poster/original.webp", "card")
if !strings.Contains(got, "/w500.webp") {
t.Fatalf("resolved URL = %q, want w500 poster variant", got)
}
if resolver.variant != "featured" {
t.Fatalf("resolver variant = %q, want featured", resolver.variant)
}
}
func absCoverResolverForTest(t *testing.T, handler *abs.Handler) func(context.Context, string, string) string {
t.Helper()
field := reflect.ValueOf(handler).Elem().FieldByName("deps").FieldByName("CoverResolver")
return reflect.NewAt(field.Type(), unsafe.Pointer(field.UnsafeAddr())).Elem().Interface().(func(context.Context, string, string) string)
}
type recordingImageResolver struct {
path string
variant string
}
func (r *recordingImageResolver) ResolveImageURL(_ context.Context, path string, variant string) string {
r.path = path
r.variant = variant
return "resolved://" + path
}
func (r *recordingImageResolver) ResolveImageURLs(_ context.Context, paths []string, variant string) map[string]string {
out := make(map[string]string, len(paths))
for _, path := range paths {
out[path] = r.ResolveImageURL(context.Background(), path, variant)
}
return out
}