Ctrl K
ComunidadGuías…

store_test.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
package main

import (
	"os"
	"path/filepath"
	"slices"
	"testing"

	"github.com/sophotechlabs/spinoza/internal/api"
	"github.com/sophotechlabs/spinoza/internal/checks"
	settingsstore "github.com/sophotechlabs/spinoza/internal/settings"
	pastore "github.com/sophotechlabs/spinoza/internal/store"
)

func TestTheFlagAloneAllowsANodeShell(t *testing.T) {
	allow := allowNodeShell(true, settingsstore.Memory())

	if !allow() {
		t.Fatal("--node-shell did not allow a node shell")
	}
}

func TestWithoutTheFlagTheStoredSettingDecides(t *testing.T) {
	store := settingsstore.Memory()
	allow := allowNodeShell(false, store)

	if allow() {
		t.Fatal("a node shell was allowed before anything turned it on")
	}

	err := store.Merge(map[string]string{settingsstore.NodeShellKey: "on"})
	if err != nil {
		t.Fatalf("merge: %v", err)
	}

	if !allow() {
		t.Fatal("turning the setting on did not reach a shell asked for afterwards")
	}

	off := store.Merge(map[string]string{settingsstore.NodeShellKey: "off"})
	if off != nil {
		t.Fatalf("merge: %v", off)
	}

	if allow() {
		t.Fatal("turning the setting off left node shells allowed")
	}
}

func TestCustomColumnsFollowStoredSettings(t *testing.T) {
	store := settingsstore.Memory()
	columns := customColumns(store)

	if got := columns(); len(got) != 0 {
		t.Fatalf("columns before configuration = %v", got)
	}

	err := store.Merge(map[string]string{
		settingsstore.ColumnsKey: `{"/v1/pods":[{"name":"Node name","path":".spec.nodeName"}]}`,
	})
	if err != nil {
		t.Fatalf("store columns: %v", err)
	}
	got := columns()
	want := api.CustomColumn{Name: "Node name", Path: ".spec.nodeName"}
	if len(got["/v1/pods"]) != 1 || got["/v1/pods"][0] != want {
		t.Fatalf("columns after configuration = %v, want %v", got, want)
	}

	err = store.Merge(map[string]string{settingsstore.ColumnsKey: "not json"})
	if err != nil {
		t.Fatalf("store malformed columns: %v", err)
	}
	if got := columns(); len(got) != 0 {
		t.Fatalf("malformed columns = %v, want none", got)
	}
}

func TestReadableNamespacesFollowStoredSettings(t *testing.T) {
	store := settingsstore.Memory()
	named := readableNamespaces(store)

	if got := named(); len(got) != 0 {
		t.Fatalf("namespaces before configuration = %v", got)
	}

	err := store.Merge(map[string]string{
		settingsstore.NamespacesKey: `{"spinoza-eks-editor":["payments"]}`,
	})
	if err != nil {
		t.Fatalf("store namespaces: %v", err)
	}
	got := named()
	if len(got["spinoza-eks-editor"]) != 1 || got["spinoza-eks-editor"][0] != "payments" {
		t.Fatalf("namespaces after configuration = %v, want payments", got)
	}

	err = store.Merge(map[string]string{settingsstore.NamespacesKey: "not json"})
	if err != nil {
		t.Fatalf("store malformed namespaces: %v", err)
	}
	if got := named(); len(got) != 0 {
		t.Fatalf("malformed namespaces = %v, want none", got)
	}
}

func TestTheStoreIsReadFromTheUsualPlace(t *testing.T) {
	dir := t.TempDir()
	t.Setenv("HOME", dir)
	t.Setenv("XDG_CONFIG_HOME", dir)
	path, err := settingsstore.DefaultPath()
	if err != nil {
		t.Fatalf("path: %v", err)
	}
	mkdirErr := os.MkdirAll(filepath.Dir(path), 0o700)
	if mkdirErr != nil {
		t.Fatalf("mkdir: %v", mkdirErr)
	}
	body := `{"values":{"` + settingsstore.NodeShellKey + `":"on"}}`
	writeErr := os.WriteFile(path, []byte(body), 0o600)
	if writeErr != nil {
		t.Fatalf("write: %v", writeErr)
	}

	store := settingsStore(t.Context())

	if !store.On(settingsstore.NodeShellKey) {
		t.Fatal("the settings written on disk were not read back")
	}
}

func TestNowhereToKeepSettingsStillLeavesAStore(t *testing.T) {
	t.Setenv("HOME", "")
	t.Setenv("XDG_CONFIG_HOME", "")

	store := settingsStore(t.Context())

	if store == nil {
		t.Fatal("settings with nowhere to live left no store at all")
	}
	err := store.Merge(map[string]string{settingsstore.NodeShellKey: "on"})
	if err != nil {
		t.Fatalf("merge: %v", err)
	}
	if !store.On(settingsstore.NodeShellKey) {
		t.Fatal("a store with nowhere to write forgot what it was told")
	}
}

func TestUnreadableSettingsStillLeaveAStore(t *testing.T) {
	dir := t.TempDir()
	t.Setenv("HOME", dir)
	t.Setenv("XDG_CONFIG_HOME", dir)
	path, err := settingsstore.DefaultPath()
	if err != nil {
		t.Fatalf("path: %v", err)
	}
	mkdirErr := os.MkdirAll(filepath.Dir(path), 0o700)
	if mkdirErr != nil {
		t.Fatalf("mkdir: %v", mkdirErr)
	}
	writeErr := os.WriteFile(path, []byte("{not json"), 0o600)
	if writeErr != nil {
		t.Fatalf("write: %v", writeErr)
	}

	store := settingsStore(t.Context())

	if store == nil {
		t.Fatal("settings that cannot be read left no store at all")
	}
	if store.On(settingsstore.NodeShellKey) {
		t.Fatal("settings that cannot be read turned a node shell on")
	}
}

func TestBaselinesAreKeptBesideTheSettings(t *testing.T) {
	dir := t.TempDir()
	t.Setenv("HOME", dir)
	t.Setenv("XDG_CONFIG_HOME", dir)

	store := baselineStore()

	taken := checks.Baseline{
		TakenAt: "2026-08-30T00:00:00Z",
		Checks:  []string{"privileged-containers"},
	}
	if err := store.Save("https://one.example", taken); err != nil {
		t.Fatalf("save: %v", err)
	}
	if _, ok := store.Load("https://one.example"); !ok {
		t.Fatal("a baseline saved through the store could not be read back")
	}
}

func TestNowhereToKeepBaselinesStillLeavesAStore(t *testing.T) {
	t.Setenv("HOME", "")
	t.Setenv("XDG_CONFIG_HOME", "")

	store := baselineStore()

	if _, ok := store.Load("https://one.example"); ok {
		t.Fatal("a store with nowhere to write produced a baseline")
	}
}

func TestHistoryIsKeptInTheUsualPlace(t *testing.T) {
	dir := t.TempDir()
	t.Setenv("HOME", dir)
	t.Setenv("XDG_CONFIG_HOME", dir)

	store := historyStore(t.Context())
	t.Cleanup(func() { _ = store.Close() })

	if store.Reason() != "" {
		t.Fatalf("reason = %q, want a store that records", store.Reason())
	}
	path, err := pastore.DefaultPath()
	if err != nil {
		t.Fatalf("path: %v", err)
	}
	if _, statErr := os.Stat(path); statErr != nil {
		t.Fatalf("the history file was not created at %s: %v", path, statErr)
	}
}

func TestNowhereToKeepHistoryStillLeavesAStore(t *testing.T) {
	t.Setenv("HOME", "")
	t.Setenv("XDG_CONFIG_HOME", "")

	store := historyStore(t.Context())
	t.Cleanup(func() { _ = store.Close() })

	if store == nil {
		t.Fatal("history with nowhere to live left no store at all")
	}
	if store.Reason() == "" {
		t.Skip("this platform still names a config directory without HOME")
	}
	if err := store.For("https://p-mk1:6443").Record(t.Context(), pastore.Entry{Name: "web"}); err != nil {
		t.Fatalf("record: %v, want a quiet no-op", err)
	}
}

func TestAHistoryFileThatCannotBeReadStillLeavesAStore(t *testing.T) {
	dir := t.TempDir()
	t.Setenv("HOME", dir)
	t.Setenv("XDG_CONFIG_HOME", dir)
	path, err := pastore.DefaultPath()
	if err != nil {
		t.Fatalf("path: %v", err)
	}
	if mkdirErr := os.MkdirAll(filepath.Dir(path), 0o700); mkdirErr != nil {
		t.Fatalf("mkdir: %v", mkdirErr)
	}
	if writeErr := os.WriteFile(path, []byte("not a database"), 0o600); writeErr != nil {
		t.Fatalf("write: %v", writeErr)
	}

	store := historyStore(t.Context())
	t.Cleanup(func() { _ = store.Close() })

	if store == nil {
		t.Fatal("a broken history file left no store at all")
	}
	if store.Reason() == "" {
		t.Fatal("a broken history file was reported as recording")
	}
}

func TestNamespacesComeBackFromTheirJSON(t *testing.T) {
	held := parseNamespaces(`{"spinoza-eks-editor":["payments","storefront"]}`)

	if !slices.Equal(held["spinoza-eks-editor"], []string{"payments", "storefront"}) {
		t.Fatalf("read %v", held)
	}
}

func TestAnythingThatIsNotNamespacesReadsAsNone(t *testing.T) {
	for _, raw := range []string{"", "not json", "[]", "null", "42", `{"ctx":"payments"}`} {
		if got := parseNamespaces(raw); len(got) != 0 {
			t.Fatalf("%q read as %v", raw, got)
		}
	}
}