Files
silo-server/internal/config/db_loader_test.go
T
5afe56cfc0 feat(jellycompat): add runtime-managed Jellyfin Web compatibility (#77)
* feat(jellycompat): install web assets at runtime

* fix(jellycompat): recover stale web operation locks

* fix(jellycompat): harden web component management

* feat(admin): refine compat settings and restart status

* chore(dev): add hot-reload docker compose stack

* fix(dev): include npm in hot-reload backend

* feat(admin): refine Jellyfin compatibility settings

* feat(settings): improve jellyfin proxy summary

* feat(settings): improve jellyfin web controls

* fix(settings): update jellyfin web removal status

* fix(settings): enable jellyfin web after install

* feat(jellycompat): auto-select web ui version

* test(api): update rate limit handler setup

* feat(jellycompat): refine web ui install onboarding

* fix(jellycompat): address web ui install review issues

* fix(onboarding): mirror jellyfin api runtime status

* fix(admin): remove global restart banner

* fix(settings): gate restart required tracking

* fix(jellyfin): ignore live settings for restart status

* fix(jellyfin): avoid restart for live compat settings

* fix(subtitles): normalize AI language codes

* fix(catalog): support partial title search tokens

* feat(branding): add white-label customization

* Add push relay engineering plan

- Document relay API contracts, APNs/FCM behavior, auth, storage, and ops
- Capture implementation plan, provider references, decisions, and README

---------

Co-authored-by: Quick <31828688+Quick104@users.noreply.github.com>
2026-06-15 09:34:08 -04:00

175 lines
5.5 KiB
Go

package config
import (
"os"
"strings"
"testing"
"time"
)
func TestLoadFromDBMetadataPresignExpiry(t *testing.T) {
cfg, err := LoadFromDB(map[string]string{})
if err != nil {
t.Fatalf("LoadFromDB() returned error: %v", err)
}
if cfg.S3.MetadataPresignExpiry != 4*time.Hour {
t.Fatalf("default metadata presign expiry = %s, want 4h", cfg.S3.MetadataPresignExpiry)
}
cfg, err = LoadFromDB(map[string]string{"s3.metadata_presign_expiry": "90m"})
if err != nil {
t.Fatalf("LoadFromDB() with metadata expiry returned error: %v", err)
}
if cfg.S3.MetadataPresignExpiry != 90*time.Minute {
t.Fatalf("configured metadata presign expiry = %s, want 90m", cfg.S3.MetadataPresignExpiry)
}
}
func TestLoadFromDBMetadataPresignExpiryRejectsInvalidDuration(t *testing.T) {
_, err := LoadFromDB(map[string]string{"s3.metadata_presign_expiry": "soon"})
if err == nil {
t.Fatal("LoadFromDB() error = nil, want invalid duration error")
}
if !strings.Contains(err.Error(), "s3.metadata_presign_expiry") {
t.Fatalf("LoadFromDB() error = %v, want key name", err)
}
}
func TestLoadFromDBJellyfinWebEnabledDefaultsToTrue(t *testing.T) {
cfg, err := LoadFromDB(map[string]string{})
if err != nil {
t.Fatalf("LoadFromDB() returned error: %v", err)
}
if !cfg.JellyfinCompat.WebEnabled {
t.Fatal("JellyfinCompat.WebEnabled = false, want default true")
}
cfg, err = LoadFromDB(map[string]string{"jellyfin_compat.web_enabled": "false"})
if err != nil {
t.Fatalf("LoadFromDB() returned error: %v", err)
}
if cfg.JellyfinCompat.WebEnabled {
t.Fatal("JellyfinCompat.WebEnabled = true, want configured false")
}
}
func TestLoadFromDBAudiobookshelfCompatFlagGatesCompatListener(t *testing.T) {
cfg, err := LoadFromDB(map[string]string{})
if err != nil {
t.Fatalf("LoadFromDB() returned error: %v", err)
}
if cfg.AudiobookshelfCompat.Listen != ":13378" {
t.Fatalf("default audiobooks listener = %q, want default :13378", cfg.AudiobookshelfCompat.Listen)
}
cfg, err = LoadFromDB(map[string]string{"audiobookshelf_compat.enabled": "false"})
if err != nil {
t.Fatalf("LoadFromDB() returned error: %v", err)
}
if cfg.AudiobookshelfCompat.Listen != "" {
t.Fatalf("disabled audiobooks listener = %q, want empty", cfg.AudiobookshelfCompat.Listen)
}
cfg, err = LoadFromDB(map[string]string{"audiobookshelf_compat.enabled": "true"})
if err != nil {
t.Fatalf("LoadFromDB() returned error: %v", err)
}
if cfg.AudiobookshelfCompat.Listen != ":13378" {
t.Fatalf("enabled audiobooks listener = %q, want default :13378", cfg.AudiobookshelfCompat.Listen)
}
}
func TestLoadFromDBJellyfinCompatEnabledPreservesLegacyListenerDefault(t *testing.T) {
cfg, err := LoadFromDB(map[string]string{})
if err != nil {
t.Fatalf("LoadFromDB() returned error: %v", err)
}
if !cfg.JellyfinCompat.Enabled {
t.Fatal("JellyfinCompat.Enabled = false, want legacy default true when listener would bind")
}
if cfg.JellyfinCompat.Listen == "" {
t.Fatal("JellyfinCompat.Listen is empty, want default listener")
}
cfg, err = LoadFromDB(map[string]string{"jellyfin_compat.listen": ":19096"})
if err != nil {
t.Fatalf("LoadFromDB() returned error: %v", err)
}
if !cfg.JellyfinCompat.Enabled {
t.Fatal("JellyfinCompat.Enabled = false, want true when legacy listener is configured")
}
if cfg.JellyfinCompat.Listen != ":19096" {
t.Fatalf("JellyfinCompat.Listen = %q, want configured listener", cfg.JellyfinCompat.Listen)
}
}
func TestLoadFromDBJellyfinCompatEnabledRespectsExplicitDisable(t *testing.T) {
cfg, err := LoadFromDB(map[string]string{
"jellyfin_compat.enabled": "false",
"jellyfin_compat.listen": ":19096",
})
if err != nil {
t.Fatalf("LoadFromDB() returned error: %v", err)
}
if cfg.JellyfinCompat.Enabled {
t.Fatal("JellyfinCompat.Enabled = true, want configured false")
}
_, err = LoadFromDB(map[string]string{"jellyfin_compat.enabled": "maybe"})
if err == nil {
t.Fatal("LoadFromDB() error = nil, want invalid bool error")
}
if !strings.Contains(err.Error(), "jellyfin_compat.enabled") {
t.Fatalf("LoadFromDB() error = %v, want key name", err)
}
}
func TestYAMLToSettingsMapJellyfinCompatEnabledPreservesLegacyListener(t *testing.T) {
m := yamlSettingsMapFromString(t, `
jellyfin_compat:
listen: ":19096"
`)
if got := m["jellyfin_compat.enabled"]; got != "true" {
t.Fatalf("jellyfin_compat.enabled = %q, want true", got)
}
if got := m["jellyfin_compat.listen"]; got != ":19096" {
t.Fatalf("jellyfin_compat.listen = %q, want configured listener", got)
}
}
func TestYAMLToSettingsMapJellyfinCompatEnabledRespectsExplicitDisable(t *testing.T) {
m := yamlSettingsMapFromString(t, `
jellyfin_compat:
enabled: false
listen: ":19096"
`)
if got := m["jellyfin_compat.enabled"]; got != "false" {
t.Fatalf("jellyfin_compat.enabled = %q, want false", got)
}
}
func TestYAMLToSettingsMapJellyfinCompatEnabledDefaultsToLegacyListener(t *testing.T) {
m := yamlSettingsMapFromString(t, `server:
mode: integrated
`)
if got := m["jellyfin_compat.enabled"]; got != "true" {
t.Fatalf("jellyfin_compat.enabled = %q, want true for default listener", got)
}
if got := m["jellyfin_compat.listen"]; got == "" {
t.Fatal("jellyfin_compat.listen is empty, want default listener")
}
}
func yamlSettingsMapFromString(t *testing.T, body string) map[string]string {
t.Helper()
path := t.TempDir() + "/silo.yaml"
if err := os.WriteFile(path, []byte(body), 0o600); err != nil {
t.Fatalf("WriteFile() returned error: %v", err)
}
m, err := YAMLToSettingsMap(path)
if err != nil {
t.Fatalf("YAMLToSettingsMap() returned error: %v", err)
}
return m
}