package config import ( "path/filepath" "testing" ) func TestDefaultsValid(t *testing.T) { t.Setenv("RM_LISTEN", ":8080") t.Setenv("RM_DATA_DIR", "/tmp/rm-test") c, err := Load("") if err != nil { t.Fatalf("load: %v", err) } if c.Listen != ":8080" { t.Errorf("listen: %q", c.Listen) } if c.SecretKeyFile != "/tmp/rm-test/secret.key" { t.Errorf("secret_key_file default: %q", c.SecretKeyFile) } } func TestEnvOverridesYAML(t *testing.T) { dir := t.TempDir() yamlPath := filepath.Join(dir, "rm.yaml") body := []byte(`listen: ":7000"` + "\n" + `data_dir: "/var/lib/rm"` + "\n" + `base_url: "https://yaml.example"` + "\n") if err := writeFile(yamlPath, body); err != nil { t.Fatal(err) } t.Setenv("RM_LISTEN", ":9999") t.Setenv("RM_BASE_URL", "https://env.example") c, err := Load(yamlPath) if err != nil { t.Fatalf("load: %v", err) } if c.Listen != ":9999" { t.Errorf("env should win: %q", c.Listen) } if c.BaseURL != "https://env.example" { t.Errorf("env should win: %q", c.BaseURL) } if c.DataDir != "/var/lib/rm" { t.Errorf("yaml should fill: %q", c.DataDir) } } func TestTrustedProxyParsing(t *testing.T) { t.Setenv("RM_LISTEN", ":8080") t.Setenv("RM_DATA_DIR", "/tmp/x") t.Setenv("RM_TRUSTED_PROXY", "10.0.0.0/8, 192.168.1.0/24") c, err := Load("") if err != nil { t.Fatalf("load: %v", err) } if len(c.TrustedProxies) != 2 { t.Fatalf("want 2 proxies, got %v", c.TrustedProxies) } if c.TrustedProxies[0] != "10.0.0.0/8" || c.TrustedProxies[1] != "192.168.1.0/24" { t.Errorf("parsed: %v", c.TrustedProxies) } } func TestTrustedProxyRejectsGarbage(t *testing.T) { t.Setenv("RM_LISTEN", ":8080") t.Setenv("RM_DATA_DIR", "/tmp/x") t.Setenv("RM_TRUSTED_PROXY", "not-a-cidr") if _, err := Load(""); err == nil { t.Fatal("expected validation error, got nil") } } func TestCookieSecureDefaultAndOverride(t *testing.T) { t.Setenv("RM_LISTEN", ":8080") t.Setenv("RM_DATA_DIR", "/tmp/x") c, err := Load("") if err != nil { t.Fatalf("load: %v", err) } if !c.CookieSecure { t.Errorf("CookieSecure should default to true") } t.Setenv("RM_COOKIE_SECURE", "false") c, err = Load("") if err != nil { t.Fatalf("load: %v", err) } if c.CookieSecure { t.Errorf("CookieSecure should be false when RM_COOKIE_SECURE=false") } } func TestMetricsAuthGates(t *testing.T) { t.Setenv("RM_LISTEN", ":8080") t.Setenv("RM_DATA_DIR", "/tmp/x") c, err := Load("") if err != nil { t.Fatalf("load: %v", err) } if c.MetricsAuthEnabled() { t.Errorf("metrics endpoint should be off by default") } t.Setenv("RM_METRICS_TOKEN", "s3cr3t-token-with-enough-bytes") t.Setenv("RM_METRICS_TRUSTED_CIDR", "10.0.0.0/8, 192.168.1.0/24") c, err = Load("") if err != nil { t.Fatalf("load: %v", err) } if c.MetricsToken != "s3cr3t-token-with-enough-bytes" { t.Errorf("token: %q", c.MetricsToken) } if got := c.MetricsTrustedCIDRs; len(got) != 2 || got[0] != "10.0.0.0/8" || got[1] != "192.168.1.0/24" { t.Errorf("cidrs: %v", got) } if !c.MetricsAuthEnabled() { t.Errorf("MetricsAuthEnabled should be true") } } func TestMetricsTrustedCIDRRejectsGarbage(t *testing.T) { t.Setenv("RM_LISTEN", ":8080") t.Setenv("RM_DATA_DIR", "/tmp/x") t.Setenv("RM_METRICS_TRUSTED_CIDR", "garbage") if _, err := Load(""); err == nil { t.Fatal("expected validation error, got nil") } } func writeFile(path string, body []byte) error { return writeFileImpl(path, body) }