package admin import ( "io" "log/slog" "net/http" "net/http/httptest" "os" "path/filepath" "strings" "testing" "git.veillax.com/Veillax/spinner/internal/config" "git.veillax.com/Veillax/spinner/internal/health" "git.veillax.com/Veillax/spinner/internal/proxy" ) func newAdmin(t *testing.T, cfg string) http.Handler { t.Helper() log := slog.New(slog.NewTextHandler(io.Discard, nil)) path := filepath.Join(t.TempDir(), "spinner.json") if err := os.WriteFile(path, []byte(cfg), 0o600); err != nil { t.Fatal(err) } m, err := config.NewManager(path, log) if err != nil { t.Fatal(err) } h := health.New(log) return (&Admin{Cfg: m, Health: h, Proxy: proxy.New(m, h, log), Token: "secret"}).Handler() } func get(h http.Handler, path, token string) *httptest.ResponseRecorder { req := httptest.NewRequest("GET", path, nil) if token != "" { req.Header.Set("Authorization", "Bearer "+token) } rec := httptest.NewRecorder() h.ServeHTTP(rec, req) return rec } // The page reads .length on these lists, so an empty config must give [] and never null. func TestEmptyConfigGivesEmptyLists(t *testing.T) { for _, cfg := range []string{`{}`, `{"servers":[]}`} { h := newAdmin(t, cfg) if body := get(h, "/api/overview", "secret").Body.String(); !strings.Contains(body, `"servers":[]`) { t.Errorf("%s: overview servers not an empty list: %s", cfg, body) } if body := get(h, "/api/config", "secret").Body.String(); !strings.Contains(body, `"servers":[]`) { t.Errorf("%s: config servers not an empty list: %s", cfg, body) } } } func TestAuthRequired(t *testing.T) { h := newAdmin(t, `{}`) for _, p := range []string{"/api/overview", "/api/config", "/metrics"} { if c := get(h, p, "").Code; c != http.StatusUnauthorized { t.Errorf("%s without token: %d", p, c) } if c := get(h, p, "wrong").Code; c != http.StatusUnauthorized { t.Errorf("%s with wrong token: %d", p, c) } if c := get(h, p, "secret").Code; c != http.StatusOK { t.Errorf("%s with token: %d", p, c) } } if c := get(h, "/", "").Code; c != http.StatusOK { t.Errorf("page should load without a token: %d", c) } }