package rules import "testing" const configWithBadTag = `package config type Config struct { Host string ` + "`" + `env:"EINHERJAR_PG_HOST,required"` + "`" + ` Bad string ` + "`" + `env:"EINHERJAR_PG_DATABASE"` + "`" + ` App string ` + "`" + `env:"APP_ENV" envDefault:"local"` + "`" + ` } ` func findingsFor(fs []Finding, ruleID string) []Finding { var out []Finding for _, f := range fs { if f.RuleID == ruleID { out = append(out, f) } } return out } func TestUnknownEnvVarFires(t *testing.T) { SetKnownEnvVars(map[string]struct{}{"EINHERJAR_PG_HOST": {}}) defer SetKnownEnvVars(nil) got := findingsFor(Run(configWithBadTag), "config.unknown-env-var") if len(got) != 1 { t.Fatalf("want 1 unknown-env-var finding, got %d: %+v", len(got), got) } if got[0].Severity != SeverityError { t.Errorf("want error severity, got %s", got[0].Severity) } // EINHERJAR_PG_HOST is known and APP_ENV is app-owned — neither may be flagged. for _, f := range got { if f.Message == "" || f.Line == 0 { t.Errorf("finding should carry a message and line: %+v", f) } } } func TestUnknownEnvVarNoopWithoutIndex(t *testing.T) { SetKnownEnvVars(nil) // simulate no injected index if got := findingsFor(Run(configWithBadTag), "config.unknown-env-var"); len(got) != 0 { t.Errorf("rule must be a no-op without an injected var set, got %+v", got) } } func TestUnknownEnvVarCleanConfig(t *testing.T) { SetKnownEnvVars(map[string]struct{}{"EINHERJAR_PG_HOST": {}, "EINHERJAR_PG_NAME": {}}) defer SetKnownEnvVars(nil) clean := `package config type Config struct { Host string ` + "`" + `env:"EINHERJAR_PG_HOST,required"` + "`" + ` Name string ` + "`" + `env:"EINHERJAR_PG_NAME,required"` + "`" + ` } ` if got := findingsFor(Run(clean), "config.unknown-env-var"); len(got) != 0 { t.Errorf("clean config should not fire, got %+v", got) } }