Fix the Servers page failing when no servers are configured
An empty server list was sent as null, so the page threw on .length and showed only the loading placeholder. The API now always returns a list, the page tolerates null, and tests cover the empty config and the token. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
8f01c6213f
commit
4afbf2d266
4 files changed
+78
-3
No files matched your search
@@ -71,7 +71,7 @@ func (a *Admin) overview(w http.ResponseWriter, r *http.Request) {
|
||||
for _, s := range snap.Servers {
|
||||
stats[s.Name] = s
|
||||
}
|
||||
var servers []serverView
|
||||
servers := []serverView{}
|
||||
for _, s := range a.Cfg.Current().Servers {
|
||||
v := serverView{Server: s}
|
||||
if h, ok := states[s.Name]; ok {
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
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)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user