package config
import (
"os"
"path/filepath"
"testing"
)
func write(t *testing.T, body string) string {
t.Helper()
dir := t.TempDir()
p := filepath.Join(dir, "config.toml")
if err := os.WriteFile(p, []byte(body), 0o600); err != nil {
t.Fatal(err)
}
return p
}
// disc_prefix used to be stored verbatim and never read, so a typo or an
// invented value was accepted and then silently did nothing.
func TestDiscPrefixRejectsUnknownValues(t *testing.T) {
// Load reads the real config path too, so the values are set by file here.
for _, good := range []string{"always", "never", "auto", "AUTO", " auto "} {
if _, err := Load(write(t, "disc_prefix = \""+good+"\"")); err != nil {
t.Errorf("disc_prefix = %q should be accepted: %v", good, err)
}
}
for _, bad := range []string{"sometimes", "", "true"} {
if _, err := Load(write(t, "disc_prefix = \""+bad+"\"")); err == nil {
t.Errorf("disc_prefix = %q should be rejected", bad)
}
}
}
// An unrecognised verify_decode used to be stored verbatim and then matched none
// of the modes the verifier knows, so a typo quietly turned the only end-to-end
// check of the audio that gets written into a no-op.
func TestVerifyDecodeRejectsUnknownValues(t *testing.T) {
for _, good := range []string{"all", "sample", "none", "SAMPLE", " all "} {
if _, err := Load(write(t, "verify_decode = \""+good+"\"")); err != nil {
t.Errorf("verify_decode = %q should be accepted: %v", good, err)
}
}
for _, bad := range []string{"", "sample2", "yes", "true"} {
if _, err := Load(write(t, "verify_decode = \""+bad+"\"")); err == nil {
t.Errorf("verify_decode = %q should be rejected", bad)
}
}
}
// libvorbis takes 1-10, and a value outside that used to reach ffmpeg, which
// failed the whole album with an encoder error rather than a configuration one.
func TestQualityRangeIsChecked(t *testing.T) {
for _, good := range []string{"1", "9", "10"} {
if _, err := Load(write(t, "quality = "+good)); err != nil {
t.Errorf("quality = %s should be accepted: %v", good, err)
}
}
for _, bad := range []string{"0", "11", "-3"} {
if _, err := Load(write(t, "quality = "+bad)); err == nil {
t.Errorf("quality = %s should be rejected", bad)
}
}
}
// The ignore list lives beside staging, archive and library, one folder name per
// line, because it describes this library rather than this machine.
func TestIgnoreListRoundTrips(t *testing.T) {
root := t.TempDir()
cfg := Defaults()
cfg.Root = root
got, err := cfg.LoadIgnore()
if err != nil {
t.Fatalf("a missing ignore file is not an error: %v", err)
}
if len(got) != 0 {
t.Errorf("a missing ignore file produced %v", got)
}
if added, err := cfg.AddIgnore("Some Junk Folder"); err != nil || !added {
t.Fatalf("AddIgnore: %v %v", added, err)
}
if added, err := cfg.AddIgnore("Some Junk Folder"); err != nil || added {
t.Errorf("adding the same name twice should report no change: %v %v", added, err)
}
if added, err := cfg.AddIgnore(" "); err != nil || added {
t.Errorf("a blank name should be refused: %v %v", added, err)
}
if _, err := cfg.AddIgnore("another one"); err != nil {
t.Fatal(err)
}
got, err = cfg.LoadIgnore()
if err != nil {
t.Fatal(err)
}
if !got["Some Junk Folder"] || !got["another one"] || len(got) != 2 {
t.Errorf("ignore set = %v", got)
}
if removed, err := cfg.RemoveIgnore("Some Junk Folder"); err != nil || !removed {
t.Fatalf("RemoveIgnore: %v %v", removed, err)
}
if removed, err := cfg.RemoveIgnore("not there"); err != nil || removed {
t.Errorf("removing something absent should report no change: %v %v", removed, err)
}
got, _ = cfg.LoadIgnore()
if got["Some Junk Folder"] || !got["another one"] {
t.Errorf("ignore set after removal = %v", got)
}
}
// Hand-editing the file has to work: it is a plain list with comments.
func TestIgnoreListIsHandEditable(t *testing.T) {
root := t.TempDir()
cfg := Defaults()
cfg.Root = root
body := "# my notes\n\n spaced name \n# another comment\nsecond\n"
if err := os.WriteFile(cfg.IgnorePath(), []byte(body), 0o644); err != nil {
t.Fatal(err)
}
got, err := cfg.LoadIgnore()
if err != nil {
t.Fatal(err)
}
if !got["spaced name"] || !got["second"] || len(got) != 2 {
t.Errorf("ignore set = %v", got)
}
}