package main import ( "os" "path/filepath" "testing" ) func TestConfigurationRequiresDatabaseAndExternalKey(t *testing.T) { t.Setenv("BELL_DB_DSN", "") t.Setenv("BELL_AUDIT_KEYS_FILE", "") if _, err := loadConfiguration(); err == nil { t.Fatal("missing Bell database was accepted") } t.Setenv("BELL_DB_DSN", "postgres://bell@127.0.0.1/yovision") t.Setenv("BELL_AUDIT_KEYS_FILE", "relative.json") if _, err := loadConfiguration(); err == nil { t.Fatal("relative Bell key file was accepted") } } func TestAlertsAreDisabledByDefaultAndConsoleRequiresLoopbackContext(t *testing.T) { t.Setenv("BELL_DB_DSN", "postgres://bell@127.0.0.1/yovision") t.Setenv("BELL_AUDIT_KEYS_FILE", filepath.Join(t.TempDir(), "audit.json")) value, err := loadConfiguration() if err != nil || value.alertsEnabled || value.alertConsoleEnabled { t.Fatalf("default alert configuration: %+v %v", value, err) } t.Setenv("BELL_ALERTS_ENABLED", "true") if _, err := loadConfiguration(); err == nil { t.Fatal("alerts without an external rule file were accepted") } t.Setenv("BELL_ALERT_RULES_FILE", filepath.Join(t.TempDir(), "rules.json")) t.Setenv("BELL_ALERT_CONSOLE_ENABLED", "true") if _, err := loadConfiguration(); err == nil { t.Fatal("console without external context was accepted") } t.Setenv("BELL_ALERT_CONSOLE_TOKEN_FILE", filepath.Join(t.TempDir(), "token")) t.Setenv("BELL_ALERT_CONSOLE_TENANT_ID", "1") t.Setenv("BELL_ALERT_CONSOLE_SITE_ID", "2") t.Setenv("BELL_ALERT_CONSOLE_ACTOR_REF", "operator:local") t.Setenv("BELL_HTTP_ADDR", "127.0.0.1:8081") value, err = loadConfiguration() if err != nil || !value.alertsEnabled || !value.alertConsoleEnabled { t.Fatalf("valid alert console configuration: %+v %v", value, err) } } func TestLoadConsoleToken(t *testing.T) { path := filepath.Join(t.TempDir(), "token") if err := os.WriteFile(path, []byte("12345678901234567890123456789012\n"), 0o600); err != nil { t.Fatal(err) } if value, err := loadConsoleToken(path); err != nil || len(value) != 32 { t.Fatalf("valid token: %q %v", value, err) } if err := os.WriteFile(path, []byte("short"), 0o600); err != nil { t.Fatal(err) } if _, err := loadConsoleToken(path); err == nil { t.Fatal("short token was accepted") } } func TestConfigurationRequiresTLSOutsideLoopback(t *testing.T) { t.Setenv("BELL_DB_DSN", "postgres://bell@127.0.0.1/yovision") t.Setenv("BELL_AUDIT_KEYS_FILE", filepath.Join(t.TempDir(), "keys.json")) t.Setenv("BELL_HTTP_ADDR", "0.0.0.0:8081") if _, err := loadConfiguration(); err == nil { t.Fatal("remote plaintext Bell bind was accepted") } t.Setenv("BELL_TLS_CERT_FILE", filepath.Join(t.TempDir(), "server.crt")) t.Setenv("BELL_TLS_KEY_FILE", filepath.Join(t.TempDir(), "server.key")) if _, err := loadConfiguration(); err != nil { t.Fatalf("remote TLS Bell bind rejected: %v", err) } } func TestEventIngressIsDisabledByDefaultAndRequiresExternalPolicy(t *testing.T) { t.Setenv("BELL_DB_DSN", "postgres://bell@127.0.0.1/yovision") t.Setenv("BELL_AUDIT_KEYS_FILE", filepath.Join(t.TempDir(), "audit.json")) t.Setenv("BELL_EVENT_INGRESS_ENABLED", "") value, err := loadConfiguration() if err != nil || value.eventIngressEnabled { t.Fatalf("default event ingress configuration: %+v %v", value, err) } t.Setenv("BELL_EVENT_INGRESS_ENABLED", "true") if _, err := loadConfiguration(); err == nil { t.Fatal("event ingress without keys and evidence policy was accepted") } t.Setenv("BELL_EVENT_INGRESS_KEYS_FILE", filepath.Join(t.TempDir(), "event-keys.json")) t.Setenv("BELL_EVIDENCE_FORBIDDEN_NAMES_FILE", filepath.Join(t.TempDir(), "names.txt")) value, err = loadConfiguration() if err != nil || !value.eventIngressEnabled { t.Fatalf("valid event ingress configuration rejected: %+v %v", value, err) } }