Files
doormile_backend/config/config_test.go

93 lines
3.1 KiB
Go

package config
import (
"os"
"testing"
)
// Config is read once at startup, so a mistyped env key fails silently: the
// service boots on a default and points at the wrong host, or ships with a
// security switch left off. Cheap to pin.
func setEnv(t *testing.T, key, value string) {
t.Helper()
previous, had := os.LookupEnv(key)
if value == "" {
_ = os.Unsetenv(key)
} else {
_ = os.Setenv(key, value)
}
t.Cleanup(func() {
if had {
_ = os.Setenv(key, previous)
} else {
_ = os.Unsetenv(key)
}
})
}
// The geocoder settings added for the customer app. GEOCODER_URL is what the
// place search proxies through — the app is never handed a map key, after the
// legacy rider app's key had to be revoked.
func TestGeocoderDefaultsAndOverrides(t *testing.T) {
setEnv(t, "GEOCODER_URL", "")
setEnv(t, "GEOCODER_EMAIL", "")
cfg := Load()
if cfg.GeocoderURL != "https://nominatim.openstreetmap.org" {
t.Errorf("GeocoderURL default = %q, want the Nominatim host", cfg.GeocoderURL)
}
if cfg.GeocoderEmail != "" {
t.Errorf("GeocoderEmail default = %q, want empty", cfg.GeocoderEmail)
}
setEnv(t, "GEOCODER_URL", "https://nominatim.internal")
setEnv(t, "GEOCODER_EMAIL", "ops@doormile.com")
cfg = Load()
if cfg.GeocoderURL != "https://nominatim.internal" {
t.Errorf("GEOCODER_URL was not read: got %q", cfg.GeocoderURL)
}
if cfg.GeocoderEmail != "ops@doormile.com" {
t.Errorf("GEOCODER_EMAIL was not read: got %q", cfg.GeocoderEmail)
}
}
// Every env key the service reads must actually take effect. A typo in the key
// name means the override is ignored and the default is used — which is how a
// deploy silently points at the wrong database.
func TestEnvironmentOverridesAreRead(t *testing.T) {
cases := []struct {
key string
value string
read func(*Config) string
}{
{"ENV", "production", func(c *Config) string { return c.Env }},
{"APP_PORT", "9999", func(c *Config) string { return c.Port }},
{"DB_HOST", "db.internal", func(c *Config) string { return c.DBHost }},
{"DB_NAME", "logistics_staging", func(c *Config) string { return c.DBName }},
{"DB_PORT", "6543", func(c *Config) string { return c.DBPort }},
{"REDIS_HOST", "redis.internal", func(c *Config) string { return c.RedisHost }},
{"JWT_SECRET_KEY", "a-different-secret", func(c *Config) string { return c.JWTSecret }},
{"TRUSTED_PROXIES", "10.0.0.0/8", func(c *Config) string { return c.TrustedProxies }},
{"AI_LAYER_BASE_URL", "http://ai.internal", func(c *Config) string { return c.AILayerBaseURL }},
{"ROUTE_OPTIMIZER_URL", "http://routes.internal", func(c *Config) string { return c.RouteOptimizerURL }},
}
for _, tc := range cases {
setEnv(t, tc.key, tc.value)
if got := tc.read(Load()); got != tc.value {
t.Errorf("%s set to %q but Load() read %q", tc.key, tc.value, got)
}
}
}
// An empty env var must fall through to the default rather than blanking the
// setting — an empty DB host is a service that cannot start with no clue why.
func TestEmptyEnvFallsBackToTheDefault(t *testing.T) {
setEnv(t, "DB_NAME", "")
if got := Load().DBName; got == "" {
t.Error("DBName is empty when DB_NAME is unset; a default is required")
}
}