Files
vault-tui/internal/config/resolve_test.go
T
f.weber ae30ba1240 feat(vault-tui): implement KV client and service for managing secrets
- Added internal/vault/client.go for creating a Vault client with configuration settings.
- Introduced internal/vault/errors.go to classify Vault API errors for better UI handling.
- Created internal/vault/kv.go to manage KV secrets, including listing, reading, writing, and deleting operations.
- Implemented internal/vault/mounts.go to list and describe secret engine mounts.
- Developed internal/vault/service.go to provide a unified entry point for Vault operations.
- Added internal/vault/kv_test.go for comprehensive testing of KV operations.
- Introduced internal/ui/toast.go for transient notifications in the UI.
- Added renovate.json for dependency management and updates.
2026-08-14 11:09:03 +02:00

148 lines
4.4 KiB
Go

package config
import (
"testing"
)
func envFrom(m map[string]string) Getenv {
return func(k string) (string, bool) {
v, ok := m[k]
return v, ok
}
}
func TestResolvePrecedence_Address(t *testing.T) {
f := &File{
Version: SchemaVersion,
CurrentProfile: "p1",
Defaults: Profile{Address: "https://defaults.example.com"},
Profiles: map[string]*Profile{
"p1": {Address: "https://profile.example.com"},
},
}
cases := []struct {
name string
ov Overrides
env map[string]string
want string
}{
{"builtin only", Overrides{}, nil, "https://profile.example.com"}, // profile beats defaults
{"env beats profile", Overrides{}, map[string]string{EnvAddress: "https://env.example.com"}, "https://env.example.com"},
{"flag beats env", Overrides{Address: "https://flag.example.com"}, map[string]string{EnvAddress: "https://env.example.com"}, "https://flag.example.com"},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
s, err := Resolve(f, "", c.ov, envFrom(c.env))
if err != nil {
t.Fatalf("Resolve: %v", err)
}
if s.Address != c.want {
t.Errorf("Address = %q, want %q", s.Address, c.want)
}
})
}
}
func TestResolve_DefaultsOnlyWhenNoProfile(t *testing.T) {
f := &File{Version: SchemaVersion, Defaults: Profile{Address: "https://defaults.example.com"}}
s, err := Resolve(f, "", Overrides{}, envFrom(nil))
if err != nil {
t.Fatalf("Resolve: %v", err)
}
if s.Address != "https://defaults.example.com" {
t.Errorf("Address = %q, want defaults value", s.Address)
}
}
func TestResolve_BuiltinFallback(t *testing.T) {
f := &File{Version: SchemaVersion}
s, err := Resolve(f, "", Overrides{}, envFrom(nil))
if err != nil {
t.Fatalf("Resolve: %v", err)
}
if s.Address != "https://127.0.0.1:8200" {
t.Errorf("Address = %q, want builtin default", s.Address)
}
if s.OriginOf("address").Layer != LayerBuiltin {
t.Errorf("origin layer = %q, want %q", s.OriginOf("address").Layer, LayerBuiltin)
}
}
func TestResolve_IgnoreEnvPerProfile(t *testing.T) {
ignore := true
f := &File{
Version: SchemaVersion,
Profiles: map[string]*Profile{
"staging": {Address: "https://staging.example.com", IgnoreEnv: &ignore},
},
}
s, err := Resolve(f, "staging", Overrides{}, envFrom(map[string]string{EnvAddress: "https://env.example.com"}))
if err != nil {
t.Fatalf("Resolve: %v", err)
}
if s.Address != "https://staging.example.com" {
t.Errorf("Address = %q, want profile value (env should be ignored)", s.Address)
}
}
func TestResolve_NoEnvOverrideFlag(t *testing.T) {
f := &File{
Version: SchemaVersion,
Profiles: map[string]*Profile{
"p": {Address: "https://profile.example.com"},
},
}
s, err := Resolve(f, "p", Overrides{NoEnv: true}, envFrom(map[string]string{EnvAddress: "https://env.example.com"}))
if err != nil {
t.Fatalf("Resolve: %v", err)
}
if s.Address != "https://profile.example.com" {
t.Errorf("Address = %q, want profile value (--no-env should suppress VAULT_ADDR)", s.Address)
}
}
func TestSelectProfile(t *testing.T) {
multi := &File{Profiles: map[string]*Profile{"a": {}, "b": {}}}
if _, err := SelectProfile(multi, "", envFrom(nil)); err == nil {
t.Error("expected error selecting among multiple profiles with no selection")
}
if name, err := SelectProfile(multi, "a", envFrom(nil)); err != nil || name != "a" {
t.Errorf("flag selection: got (%q, %v)", name, err)
}
if name, err := SelectProfile(multi, "", envFrom(map[string]string{EnvTUIProfile: "b"})); err != nil || name != "b" {
t.Errorf("env selection: got (%q, %v)", name, err)
}
single := &File{Profiles: map[string]*Profile{"only": {}}}
if name, err := SelectProfile(single, "", envFrom(nil)); err != nil || name != "only" {
t.Errorf("sole profile selection: got (%q, %v)", name, err)
}
empty := &File{}
if name, err := SelectProfile(empty, "", envFrom(nil)); err != nil || name != "default" {
t.Errorf("empty profiles: got (%q, %v)", name, err)
}
}
func TestResolve_ReadOnlyDefaultsSafe(t *testing.T) {
f := &File{Version: SchemaVersion}
s, err := Resolve(f, "", Overrides{}, envFrom(nil))
if err != nil {
t.Fatalf("Resolve: %v", err)
}
if !s.ReadOnly {
t.Error("ReadOnly should default to true when nothing overrides it")
}
no := false
s, err = Resolve(f, "", Overrides{ReadOnly: &no}, envFrom(nil))
if err != nil {
t.Fatalf("Resolve: %v", err)
}
if s.ReadOnly {
t.Error("--write (ReadOnly=false override) should have taken effect")
}
}