Files
pages/internal/adminapi/system_test.go
T
2026-08-15 07:13:00 +00:00

102 lines
3.1 KiB
Go

package adminapi
import (
"net/http"
"strings"
"testing"
"time"
"github.com/iceBear67/simplepages/api"
)
func TestWhoAmIReportsTheCaller(t *testing.T) {
e := newEnv(t)
e.createProject(t, "demo")
future := time.Now().Add(time.Hour).Truncate(time.Second)
proj := e.createKey(t, api.PathProjectKeys("demo"), e.adminToken,
api.CreateKeyRequest{Name: "ci", ExpiresAt: &future})
t.Run("project scope", func(t *testing.T) {
status, body := e.do(t, http.MethodGet, api.PathWhoAmI(), proj.Token, nil)
var who api.WhoAmI
mustJSON(t, status, http.StatusOK, body, &who)
if who.KeyID != proj.Key.ID {
t.Errorf("key_id = %q, want %q", who.KeyID, proj.Key.ID)
}
if who.Scope != api.ScopeProject || who.Project != "demo" || who.Name != "ci" {
t.Errorf("whoami = %+v, want scope project on demo named ci", who)
}
if who.ExpiresAt == nil || !who.ExpiresAt.Equal(future) {
t.Errorf("expires_at = %v, want %v", who.ExpiresAt, future)
}
})
t.Run("admin scope", func(t *testing.T) {
status, body := e.do(t, http.MethodGet, api.PathWhoAmI(), e.adminToken, nil)
var who api.WhoAmI
mustJSON(t, status, http.StatusOK, body, &who)
if who.Scope != api.ScopeAdmin {
t.Errorf("scope = %q, want admin", who.Scope)
}
// An admin key belongs to no project, and saying otherwise would suggest
// the caller is confined to one.
if who.Project != "" {
t.Errorf("project = %q, want empty for an admin key", who.Project)
}
})
// whoami names a credential, so it must not be cached by anything between
// the CLI and the server.
t.Run("no-store", func(t *testing.T) {
resp := e.doResp(t, http.MethodGet, api.PathWhoAmI(), proj.Token, nil)
if cc := resp.Header.Get("Cache-Control"); !strings.Contains(cc, "no-store") {
t.Errorf("Cache-Control = %q, want it to contain no-store", cc)
}
})
}
func TestSystemInfo(t *testing.T) {
e := newEnv(t)
e.createProject(t, "a")
e.createProject(t, "b")
status, body := e.do(t, http.MethodGet, api.PathSystemInfo(), e.adminToken, nil)
var info api.SystemInfo
mustJSON(t, status, http.StatusOK, body, &info)
if info.Projects != 2 {
t.Errorf("projects = %d, want 2", info.Projects)
}
if info.Deployments != 0 || info.Blobs != 0 || info.CASBytes != 0 {
t.Errorf("expected an empty CAS, got %+v", info)
}
if info.SchemaVer < 1 {
t.Errorf("schema_version = %d, want at least 1", info.SchemaVer)
}
if info.Version == "" {
t.Error("version is empty")
}
// The link mode is not known until the CAS is opened in M2; reporting an
// empty string would read as "no linking" rather than "not determined".
if info.LinkMode != "unknown" {
t.Errorf("link_mode = %q, want unknown", info.LinkMode)
}
if info.UptimeS < 0 {
t.Errorf("uptime_s = %d", info.UptimeS)
}
}
func TestSystemInfoIsAdminOnly(t *testing.T) {
e := newEnv(t)
e.createProject(t, "demo")
token := e.mintProject(t, e.projectID(t, "demo"), "ci")
status, body := e.do(t, http.MethodGet, api.PathSystemInfo(), token, nil)
if status != http.StatusForbidden {
t.Fatalf("status = %d, want 403; body: %s", status, body)
}
if got := errCode(t, body); got != api.CodeForbidden {
t.Errorf("code = %q, want %q", got, api.CodeForbidden)
}
}