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") } }