package config import ( "errors" "os" "path/filepath" "testing" "github.com/pelletier/go-toml/v2" ) func TestDefaultConfigData(t *testing.T) { data := DefaultConfigData() if data.Misc.Version != CurrentConfigVersion { t.Fatalf("version = %q, want %q", data.Misc.Version, CurrentConfigVersion) } if data.Downloads.Folder == "" { t.Fatalf("downloads folder should not be empty") } if data.Database.DownloadsPath == "" || data.Database.FailedDownloadsPath == "" { t.Fatalf("database paths should not be empty") } } func TestLoadCreatesDefaultConfigWhenMissing(t *testing.T) { tmpDir := t.TempDir() path := filepath.Join(tmpDir, "config.toml") cfg, err := Load(path) if err != nil { t.Fatalf("Load() error = %v", err) } if cfg.Path != path { t.Fatalf("path = %q, want %q", cfg.Path, path) } if _, err = os.Stat(path); err != nil { t.Fatalf("expected created config file: %v", err) } } func TestLoadOutdatedConfig(t *testing.T) { tmpDir := t.TempDir() path := filepath.Join(tmpDir, "config.toml") data := DefaultConfigData() data.Misc.Version = "1.0.0" if err := saveConfigData(path, data); err != nil { t.Fatalf("saveConfigData() error = %v", err) } _, err := Load(path) if !errors.Is(err, ErrOutdatedConfig) { t.Fatalf("Load() error = %v, want ErrOutdatedConfig", err) } } func TestUpgradeOutdatedConfig(t *testing.T) { tmpDir := t.TempDir() path := filepath.Join(tmpDir, "config.toml") data := DefaultConfigData() data.Misc.Version = "1.0.0" data.Downloads.Folder = filepath.Join(tmpDir, "Music") if err := saveConfigData(path, data); err != nil { t.Fatalf("saveConfigData() error = %v", err) } resolved, err := UpgradeOutdated(path) if err != nil { t.Fatalf("UpgradeOutdated() error = %v", err) } if resolved != path { t.Fatalf("resolved path = %q, want %q", resolved, path) } cfg, err := Load(path) if err != nil { t.Fatalf("Load() after upgrade error = %v", err) } if cfg.File.Misc.Version != CurrentConfigVersion { t.Fatalf("version = %q, want %q", cfg.File.Misc.Version, CurrentConfigVersion) } if cfg.File.Downloads.Folder != data.Downloads.Folder { t.Fatalf("downloads folder changed unexpectedly") } } func TestSessionCloneDoesNotAliasSlices(t *testing.T) { tmpDir := t.TempDir() path := filepath.Join(tmpDir, "config.toml") data := DefaultConfigData() data.Metadata.Exclude = []string{"lyrics"} data.Qobuz.Secrets = []string{"s1"} if err := saveConfigData(path, data); err != nil { t.Fatalf("saveConfigData() error = %v", err) } cfg, err := Load(path) if err != nil { t.Fatalf("Load() error = %v", err) } cfg.Session.Metadata.Exclude[0] = "comment" cfg.Session.Qobuz.Secrets[0] = "s2" if cfg.File.Metadata.Exclude[0] != "lyrics" { t.Fatalf("file metadata exclude unexpectedly mutated") } if cfg.File.Qobuz.Secrets[0] != "s1" { t.Fatalf("file qobuz secrets unexpectedly mutated") } } func TestDefaultConfigPassesValidation(t *testing.T) { d := DefaultConfigData() applyRuntimeDefaults(&d) if err := Validate(&d); err != nil { t.Fatalf("shipped defaults fail validation: %v", err) } } // TestExampleConfigIsValid guards the file users are told to copy. func TestExampleConfigIsValid(t *testing.T) { raw, err := os.ReadFile(filepath.Join("..", "..", "config.toml.example")) if err != nil { t.Skipf("example config not found: %v", err) } data := DefaultConfigData() if err := toml.Unmarshal(raw, &data); err != nil { t.Fatalf("config.toml.example does not parse: %v", err) } applyRuntimeDefaults(&data) if err := Validate(&data); err != nil { t.Fatalf("config.toml.example fails validation: %v", err) } if data.Misc.Version != CurrentConfigVersion { t.Errorf("config.toml.example version = %q, want %q", data.Misc.Version, CurrentConfigVersion) } }