102 lines
3.1 KiB
Go
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)
|
|
}
|
|
}
|