package config import ( "strings" "testing" "time" ) func TestUnifiedEnvAliases(t *testing.T) { type project struct { Server Config `json:"server"` Label string `json:"label"` } base := project{Server: Default(), Label: "base"} for _, policy := range []string{"allow", "ignore", "reject"} { t.Run(policy, func(t *testing.T) { env := map[string]string{"TEST_HTTP_ADDR": "127.0.0.1:8099", "TEST_LOG_SERVICE": "", "TEST_SERVICE": "", "TEST_LABEL": ""} opts := EnvOptions{Prefix: "TEST_", Empty: policy, Aliases: ServerEnvAliases("TEST_", "server"), Lookup: func(k string) (string, bool) { v, ok := env[k]; return v, ok }} got, err := OverlayEnv(base, opts) if policy == "reject" { if err == nil || !strings.Contains(err.Error(), "empty") { t.Fatal(err) } return } if err != nil { t.Fatal(err) } if got.Server.Address != "127.0.0.1:8099" { t.Fatal("alias ignored") } if policy == "allow" && got.Label != "" || policy == "ignore" && got.Label != "base" { t.Fatal("empty policy differs") } env["TEST_SERVER_ADDRESS"] = "127.0.0.1:9001" env["TEST_HTTP_READ_TIMEOUT"] = "3s" env["TEST_ENABLE_LOGGER"] = "false" env["TEST_TRUSTED_PROXIES"] = `["127.0.0.1"]` got, err = OverlayEnv(base, opts) if err != nil || got.Server.Address != "127.0.0.1:9001" || got.Server.HTTP.ReadTimeout != 3*time.Second || got.Server.EnableLogger || len(got.Server.TrustedProxies) != 1 { t.Fatal(got, err) } env["TEST_SERVER_ADDRESS"] = "" got, err = OverlayEnv(base, opts) if err != nil { t.Fatal(err) } expected := "" if policy == "ignore" { expected = base.Server.Address } if got.Server.Address != expected { t.Fatal("empty canonical unexpectedly fell through to alias") } }) } if base.Server.Address != ":8080" || base.Label != "base" { t.Fatal("defaults mutated") } } func TestAliasTypeErrorsDoNotExposeValue(t *testing.T) { opts := EnvOptions{Prefix: "X_", Empty: "reject", Aliases: ServerEnvAliases("X_", ""), Lookup: func(k string) (string, bool) { return "private-invalid", k == "X_HTTP_READ_TIMEOUT" }} if _, err := OverlayEnv(Default(), opts); err == nil || strings.Contains(err.Error(), "private-invalid") { t.Fatal(err) } }