222 lines
7.0 KiB
Go
222 lines
7.0 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 TestLoadFromDBRejectsInvalidSegmentRetention(t *testing.T) {
|
|
for _, value := range []string{"-1", "119", "86401"} {
|
|
t.Run(value, func(t *testing.T) {
|
|
_, err := LoadFromDB(map[string]string{playbackSegmentRetentionSettingKey: value})
|
|
if err == nil || !strings.Contains(err.Error(), playbackSegmentRetentionSettingKey) {
|
|
t.Fatalf("LoadFromDB() error = %v, want retention bounds error", 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 TestLoadFromDBPolicyEditorEnabledDefaultsFalse(t *testing.T) {
|
|
cfg, err := LoadFromDB(map[string]string{})
|
|
if err != nil {
|
|
t.Fatalf("LoadFromDB() returned error: %v", err)
|
|
}
|
|
if cfg.Policy.EditorEnabled {
|
|
t.Fatal("Policy.EditorEnabled = true, want default false")
|
|
}
|
|
|
|
cfg, err = LoadFromDB(map[string]string{"policy.editor_enabled": "true"})
|
|
if err != nil {
|
|
t.Fatalf("LoadFromDB() returned error: %v", err)
|
|
}
|
|
if !cfg.Policy.EditorEnabled {
|
|
t.Fatal("Policy.EditorEnabled = false, want configured true")
|
|
}
|
|
|
|
_, err = LoadFromDB(map[string]string{"policy.editor_enabled": "maybe"})
|
|
if err == nil {
|
|
t.Fatal("LoadFromDB() error = nil, want invalid bool error")
|
|
}
|
|
if !strings.Contains(err.Error(), "policy.editor_enabled") {
|
|
t.Fatalf("LoadFromDB() error = %v, want key name", err)
|
|
}
|
|
}
|
|
|
|
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 TestYAMLToSettingsMapPreservesExplicitlyDisabledSegmentRetention(t *testing.T) {
|
|
m := yamlSettingsMapFromString(t, `
|
|
playback:
|
|
segment_retention_seconds: 0
|
|
`)
|
|
if got := m[playbackSegmentRetentionSettingKey]; got != "0" {
|
|
t.Fatalf("segment retention = %q, want explicit disable", got)
|
|
}
|
|
}
|
|
|
|
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
|
|
}
|