package database import ( "strconv" "testing" ) // TestSettingDefaults ensures every seeded setting has a compiled default with // a valid value for its declared type. This guards against typos that would // silently fall back at runtime. func TestSettingDefaults(t *testing.T) { if len(SettingDefaults) == 0 { t.Fatal("SettingDefaults is empty") } for _, d := range SettingDefaults { if d.Key == "" { t.Errorf("default has empty key: %+v", d) continue } switch d.Type { case SettingTypeInt: if _, err := strconv.Atoi(d.Value); err != nil { t.Errorf("int setting %s default %q is not an int: %v", d.Key, d.Value, err) } if d.Min != "" { if _, err := strconv.Atoi(d.Min); err != nil { t.Errorf("int setting %s min %q is not an int", d.Key, d.Min) } } if d.Max != "" { if _, err := strconv.Atoi(d.Max); err != nil { t.Errorf("int setting %s max %q is not an int", d.Key, d.Max) } } case SettingTypeBool: if _, err := strconv.ParseBool(d.Value); err != nil { t.Errorf("bool setting %s default %q is not a bool", d.Key, d.Value) } case SettingTypeString: if d.Value == "" { t.Errorf("string setting %s has empty default", d.Key) } default: t.Errorf("setting %s has unknown type %q", d.Key, d.Type) } } } // TestSettingsRegistryGetIntClamping verifies that out-of-range DB values are // clamped to the declared min/max, and that garbage falls back to the default. func TestSettingsRegistryGetIntClamping(t *testing.T) { r := &SettingsRegistry{values: map[string]string{}, q: nil} // Seed with an over-max value; expect clamping to the max (3600). r.values["scan_poll_interval_seconds"] = "999999" if got := r.ScanPollInterval(); got.Seconds() != 3600 { t.Errorf("expected clamp to 3600, got %v", got) } // Seed with an under-min value; expect clamp to min (1). r.values["scan_poll_interval_seconds"] = "0" if got := r.ScanPollInterval(); got.Seconds() != 1 { t.Errorf("expected clamp to 1, got %v", got) } // Seed with garbage; expect fallback to default (60). r.values["scan_poll_interval_seconds"] = "not-a-number" if got := r.ScanPollInterval(); got.Seconds() != 60 { t.Errorf("expected fallback default 60, got %v", got) } } // TestSettingsRegistryGetBoolFallback verifies bool parsing and fallback. func TestSettingsRegistryGetBoolFallback(t *testing.T) { r := &SettingsRegistry{values: map[string]string{}, q: nil} r.values["auto_scan_enabled"] = "true" if !r.AutoScanEnabled() { t.Error("expected true") } r.values["auto_scan_enabled"] = "garbage" // garbage falls back to default ("true") if !r.AutoScanEnabled() { t.Error("expected fallback to default true") } } // TestLookupDefaultUnknownKey verifies unknown keys return ok=false. func TestLookupDefaultUnknownKey(t *testing.T) { if _, ok := LookupDefault("does_not_exist"); ok { t.Error("expected ok=false for unknown key") } if _, ok := LookupDefault("session_duration_seconds"); !ok { t.Error("expected ok=true for known key") } }