a73x

internal/cli/config_test.go

Ref:   Size: 2.3 KiB   History

package cli

import (
	"os"
	"path/filepath"
	"strings"
	"testing"
)

// A laptop that has never run init has no config, and that is not a failure —
// every field simply falls back.
func TestLoadConfigMissingIsEmpty(t *testing.T) {
	c, err := LoadConfig(filepath.Join(t.TempDir(), "nothing.json"))
	if err != nil {
		t.Fatalf("a missing config must not be an error: %v", err)
	}
	if c != (Config{}) {
		t.Errorf("config = %+v, want zero", c)
	}
}

// A file that exists but does not parse is named, not swallowed: this is the
// half-written config an aborted init could leave, and the user must be told
// rather than quietly served a default.
func TestLoadConfigUnreadableIsNamed(t *testing.T) {
	path := filepath.Join(t.TempDir(), "config.json")
	if err := os.WriteFile(path, []byte("{not json"), 0o600); err != nil {
		t.Fatal(err)
	}
	_, err := LoadConfig(path)
	if err == nil || !strings.Contains(err.Error(), path) {
		t.Fatalf("want an error naming %s, got %v", path, err)
	}
}

func TestSaveConfigRoundTrips(t *testing.T) {
	path := filepath.Join(t.TempDir(), "sub", "config.json")
	want := Config{URL: "http://192.0.2.10:8080", Gate: "192.0.2.10:2222", Tenant: "acme", CA: "/keys/ca", Key: "/keys/user"}
	if err := SaveConfig(path, want); err != nil {
		t.Fatal(err)
	}
	got, err := LoadConfig(path)
	if err != nil {
		t.Fatal(err)
	}
	if got != want {
		t.Errorf("round trip: got %+v want %+v", got, want)
	}
	fi, err := os.Stat(path)
	if err != nil {
		t.Fatal(err)
	}
	if perm := fi.Mode().Perm(); perm != 0o600 {
		t.Errorf("mode = %o, want 600", perm)
	}
	// The rename is the point: no temp file may be left behind to be found by
	// a later glob or backup.
	entries, err := os.ReadDir(filepath.Dir(path))
	if err != nil {
		t.Fatal(err)
	}
	if len(entries) != 1 {
		t.Errorf("directory holds %d files, want only the config", len(entries))
	}
}

// EITRI_CONFIG moves the file; unset, it sits under ~/.eitri.
func TestConfigPath(t *testing.T) {
	t.Setenv("EITRI_CONFIG", "/tmp/elsewhere.json")
	if p, err := ConfigPath(); err != nil || p != "/tmp/elsewhere.json" {
		t.Errorf("EITRI_CONFIG: got %q, %v", p, err)
	}
	t.Setenv("EITRI_CONFIG", "")
	t.Setenv("HOME", "/home/u")
	p, err := ConfigPath()
	if err != nil {
		t.Fatal(err)
	}
	if want := filepath.Join("/home/u", ".eitri", "config.json"); p != want {
		t.Errorf("default path = %q, want %q", p, want)
	}
}