git/intake/main
internal/config/config_test.go
131 lines4 KB last change raw · history
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)
	}
}