package config import ( "os" "path/filepath" "strings" "testing" ) const dispatcherFixtureID = "c046b893-8628-4589-ae50-619d049248a6" func setDispatcherEnvironment(t *testing.T) string { t.Helper() path := filepath.Join(t.TempDir(), "dispatcher.db") t.Setenv("DISPATCHER_ID", dispatcherFixtureID) t.Setenv("DISPATCHER_SECRET_KEY", "synthetic-placeholder-not-a-credential") t.Setenv("SAAS_BASE_URL", "http://127.0.0.1:8080") t.Setenv("RABBITMQ_URL", "amqp://127.0.0.1:5672/%2Fmock") t.Setenv("DISPATCHER_SQLITE_PATH", path) return path } func TestLoadDispatcherEnvironmentRefusesNonMockBeforeResources(t *testing.T) { for _, mode := range []string{"real", "mixed", ""} { t.Run(mode, func(t *testing.T) { path := setDispatcherEnvironment(t) if _, err := LoadDispatcherEnvironment(mode); err == nil || !strings.Contains(err.Error(), "Mock") { t.Fatalf("unapproved mode was admitted: %v", err) } if _, err := os.Stat(path); !os.IsNotExist(err) { t.Fatalf("mode rejection opened a database: %v", err) } }) } } func TestLoadDispatcherEnvironmentRequiresExplicitIdentityAndNoFallback(t *testing.T) { for _, name := range []string{"DISPATCHER_ID", "DISPATCHER_SECRET_KEY", "SAAS_BASE_URL", "RABBITMQ_URL", "DISPATCHER_SQLITE_PATH"} { t.Run(name, func(t *testing.T) { setDispatcherEnvironment(t) t.Setenv(name, "") if _, err := LoadDispatcherEnvironment("mock"); err == nil || !strings.Contains(err.Error(), name) { t.Fatalf("missing current config was silently defaulted: %v", err) } }) } setDispatcherEnvironment(t) t.Setenv("DISPATCHER_ID", "local-dispatcher") if _, err := LoadDispatcherEnvironment("mock"); err == nil || !strings.Contains(err.Error(), "DISPATCHER_ID") { t.Fatalf("non-UUID dispatcher identity was admitted: %v", err) } } func TestLoadDispatcherEnvironmentKeepsMockTransportsLocalAndErrorsRedacted(t *testing.T) { for _, tc := range []struct{ name, value string }{ {"SAAS_BASE_URL", "https://saas.example.invalid"}, {"RABBITMQ_URL", "amqps://mq.example.invalid:5671/%2F"}, } { t.Run(tc.name, func(t *testing.T) { setDispatcherEnvironment(t) t.Setenv(tc.name, tc.value) _, err := LoadDispatcherEnvironment("mock") if err == nil || !strings.Contains(err.Error(), tc.name) || strings.Contains(err.Error(), "synthetic-placeholder-not-a-credential") || strings.Contains(err.Error(), tc.value) { t.Fatalf("remote Mock endpoint or credential disclosure was allowed: %v", err) } }) } } func TestLoadDispatcherEnvironmentPreservesExplicitValuesWithoutOpeningSQLite(t *testing.T) { path := setDispatcherEnvironment(t) settings, err := LoadDispatcherEnvironment("mock") if err != nil { t.Fatal(err) } if settings.DispatcherID != dispatcherFixtureID || settings.SecretKey != "synthetic-placeholder-not-a-credential" || settings.SaaSBaseURL != "http://127.0.0.1:8080" || settings.RabbitMQURL != "amqp://127.0.0.1:5672/%2Fmock" || settings.SQLitePath != path { t.Fatal("explicit current environment values were changed") } if _, err := os.Stat(path); !os.IsNotExist(err) { t.Fatalf("config inspection opened the durable business database: %v", err) } }