backend requirements onthe xustomer app
This commit is contained in:
92
config/config_test.go
Normal file
92
config/config_test.go
Normal file
@@ -0,0 +1,92 @@
|
||||
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")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user