Files
ghtracker/internal/config/config_test.go
T
lukaszraczylo b74396f005 fix(collector): link a failed repository to the configured host
When the first scan of a repository failed, the repository link pointed at github.com. It now follows github.api_url: Enterprise Server hosts drop the /api/v3 suffix and Enterprise Cloud hosts drop the api. prefix.
2026-10-02 10:15:48 +01:00

148 lines
4.6 KiB
Go

package config
import (
"errors"
"os"
"path/filepath"
"testing"
"time"
)
func noFile(string) ([]byte, error) { return nil, errors.New("no file") }
func keyFile(string) ([]byte, error) { return []byte("PEM"), nil }
func env(m map[string]string) func(string) string { return func(k string) string { return m[k] } }
func valid() *Config {
return &Config{GitHub: GitHub{AppID: 1, PrivateKeyFile: "k.pem"}, Repos: []string{"a/b"}}
}
func TestFinalizeDefaults(t *testing.T) {
c := valid()
if err := c.finalize(env(nil), keyFile); err != nil {
t.Fatal(err)
}
if c.RefreshInterval != 6*time.Hour || c.Listen != ":8080" || c.Concurrency != 2 || c.MaxItems != 100 {
t.Fatalf("defaults wrong: %+v", c)
}
if c.ManualRefresh == nil || !*c.ManualRefresh {
t.Fatal("manual refresh must default to on")
}
if c.GitHub.APIURL != DefaultAPIURL || c.GitHub.PrivateKeyPEM != "PEM" {
t.Fatalf("github defaults wrong: %+v", c.GitHub)
}
if want := 12*time.Hour + 30*time.Minute; c.Thresholds.DataStaleAfter != want {
t.Fatalf("data stale = %s, want %s", c.Thresholds.DataStaleAfter, want)
}
}
func TestFinalizeEnvKeyWins(t *testing.T) {
c := valid()
c.GitHub.PrivateKeyFile = ""
if err := c.finalize(env(map[string]string{EnvPrivateKey: "ENVPEM"}), noFile); err != nil {
t.Fatal(err)
}
if c.GitHub.PrivateKeyPEM != "ENVPEM" {
t.Fatalf("got %q", c.GitHub.PrivateKeyPEM)
}
}
func TestFinalizeErrors(t *testing.T) {
tests := map[string]func(*Config){
"no app id": func(c *Config) { c.GitHub.AppID = 0 },
"no key": func(c *Config) { c.GitHub.PrivateKeyFile = "" },
"unreadable key": func(c *Config) { c.GitHub.PrivateKeyFile = "x" },
"no repos": func(c *Config) { c.Repos = nil },
"bad repo": func(c *Config) { c.Repos = []string{"justname"} },
"bad repo slashes": func(c *Config) { c.Repos = []string{"a/b/c"} },
"refresh too small": func(c *Config) { c.RefreshInterval = time.Second },
"crit below warn": func(c *Config) {
c.Thresholds.PRWarnAfter, c.Thresholds.PRCritAfter = 10*time.Hour, time.Hour
},
}
for name, mutate := range tests {
t.Run(name, func(t *testing.T) {
c := valid()
mutate(c)
if err := c.finalize(env(nil), noFile); err == nil {
t.Fatal("expected error")
}
})
}
}
func TestNormalizeReposDedupes(t *testing.T) {
got, err := normalizeRepos([]string{"A/b", " a/B ", "c/d"})
if err != nil {
t.Fatal(err)
}
if len(got) != 2 || got[0] != "A/b" || got[1] != "c/d" {
t.Fatalf("got %v", got)
}
}
func TestNegativeThresholdDisables(t *testing.T) {
c := valid()
c.Thresholds.PRCritAfter = -1
if err := c.finalize(env(nil), keyFile); err != nil {
t.Fatal(err)
}
if c.Thresholds.PRCritAfter != -1 {
t.Fatalf("negative must be kept, got %s", c.Thresholds.PRCritAfter)
}
}
func TestLoadRejectsUnknownKeysAndReadsFile(t *testing.T) {
dir := t.TempDir()
write := func(name, body string) string {
p := filepath.Join(dir, name)
if err := os.WriteFile(p, []byte(body), 0o600); err != nil {
t.Fatal(err)
}
return p
}
key := write("k.pem", "PEM")
good := write("ok.yaml", "refresh_interval: 2h\ngithub:\n app_id: 5\n private_key_file: "+key+"\nrepos: [a/b]\n")
c, err := Load(good)
if err != nil || c.RefreshInterval != 2*time.Hour || c.GitHub.PrivateKeyPEM != "PEM" {
t.Fatalf("c=%+v err=%v", c, err)
}
typo := write("typo.yaml", "refresh_intervall: 2h\ngithub:\n app_id: 5\n private_key_file: "+key+"\nrepos: [a/b]\n")
if _, err := Load(typo); err == nil {
t.Fatal("unknown key must be rejected")
}
if _, err := Load(filepath.Join(dir, "missing.yaml")); err == nil {
t.Fatal("missing file must error")
}
}
func TestManualRefreshCanBeDisabled(t *testing.T) {
off := false
c := valid()
c.ManualRefresh = &off
if err := c.finalize(env(nil), keyFile); err != nil {
t.Fatal(err)
}
if *c.ManualRefresh {
t.Fatal("explicit false must stay off")
}
}
func TestWebBase(t *testing.T) {
tests := map[string]string{
"": "https://github.com",
"https://api.github.com": "https://github.com",
"https://api.github.com/": "https://github.com",
"https://ghe.example.com/api/v3": "https://ghe.example.com",
"https://ghe.example.com/api/v3/": "https://ghe.example.com",
"http://ghe.internal:8080/api/v3": "http://ghe.internal:8080",
"https://api.acme.ghe.com": "https://acme.ghe.com",
"https://github.example.com/sub/api/v3": "https://github.example.com/sub",
"not a url": "https://github.com",
}
for in, want := range tests {
if got := WebBase(in); got != want {
t.Errorf("WebBase(%q) = %q, want %q", in, got, want)
}
}
}