Some checks failed
Go / build (.exe, 386, windows, windows-386) (push) Has been cancelled
Go / build (.exe, amd64, windows, windows-amd64) (push) Has been cancelled
Go / build (.exe, arm64, windows, windows-arm64) (push) Has been cancelled
Go / build (386, freebsd, freebsd-386) (push) Has been cancelled
Go / build (386, linux, linux-386) (push) Has been cancelled
Go / build (386, netbsd, netbsd-386) (push) Has been cancelled
Go / build (386, openbsd, openbsd-386) (push) Has been cancelled
Go / build (386, plan9, plan9-386) (push) Has been cancelled
Go / build (amd64, darwin, darwin-amd64) (push) Has been cancelled
Go / build (amd64, dragonfly, dragonfly-amd64) (push) Has been cancelled
Go / build (amd64, freebsd, freebsd-amd64) (push) Has been cancelled
Go / build (amd64, illumos, illumos-amd64) (push) Has been cancelled
Go / build (amd64, linux, linux-amd64) (push) Has been cancelled
Go / build (amd64, netbsd, netbsd-amd64) (push) Has been cancelled
Go / build (amd64, openbsd, openbsd-amd64) (push) Has been cancelled
Go / build (amd64, plan9, plan9-amd64) (push) Has been cancelled
Go / build (amd64, solaris, solaris-amd64) (push) Has been cancelled
Go / build (arm, 6, linux, linux-armv6) (push) Has been cancelled
Go / build (arm, 7, linux, linux-armv7) (push) Has been cancelled
Go / build (arm, freebsd, freebsd-arm) (push) Has been cancelled
Go / build (arm, netbsd, netbsd-arm) (push) Has been cancelled
Go / build (arm, openbsd, openbsd-arm) (push) Has been cancelled
Go / build (arm, plan9, plan9-arm) (push) Has been cancelled
Go / build (arm64, darwin, darwin-arm64) (push) Has been cancelled
Go / build (arm64, freebsd, freebsd-arm64) (push) Has been cancelled
Go / build (arm64, linux, linux-arm64) (push) Has been cancelled
Go / build (arm64, netbsd, netbsd-arm64) (push) Has been cancelled
Go / build (arm64, openbsd, openbsd-arm64) (push) Has been cancelled
Go / build (loong64, linux, linux-loong64) (push) Has been cancelled
Go / build (mips, linux, linux-mips) (push) Has been cancelled
Go / build (mips64, linux, linux-mips64) (push) Has been cancelled
Go / build (mips64le, linux, linux-mips64le) (push) Has been cancelled
Go / build (mipsle, linux, linux-mipsle) (push) Has been cancelled
Go / build (ppc64, aix, aix-ppc64) (push) Has been cancelled
Go / build (ppc64, linux, linux-ppc64) (push) Has been cancelled
Go / build (ppc64, openbsd, openbsd-ppc64) (push) Has been cancelled
Go / build (ppc64le, linux, linux-ppc64le) (push) Has been cancelled
Go / build (riscv64, freebsd, freebsd-riscv64) (push) Has been cancelled
Go / build (riscv64, linux, linux-riscv64) (push) Has been cancelled
Go / build (riscv64, openbsd, openbsd-riscv64) (push) Has been cancelled
Go / build (s390x, linux, linux-s390x) (push) Has been cancelled
Go / merge-artifacts (push) Has been cancelled
Docker Image / docker (push) Has been cancelled
139 lines
6.8 KiB
Go
139 lines
6.8 KiB
Go
package adminhttp
|
|
|
|
import (
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestNewAPIHandlerRoutesRequests(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
method string
|
|
path string
|
|
wantCall string
|
|
wantSegment string
|
|
}{
|
|
{name: "setup status", method: http.MethodGet, path: "/admin/api/setup", wantCall: "setup_status"},
|
|
{name: "setup", method: http.MethodPost, path: "/admin/api/setup", wantCall: "setup"},
|
|
{name: "login", method: http.MethodPost, path: "/admin/api/auth/login", wantCall: "login"},
|
|
{name: "logout", method: http.MethodPost, path: "/admin/api/auth/logout", wantCall: "logout"},
|
|
{name: "me", method: http.MethodGet, path: "/admin/api/me", wantCall: "me"},
|
|
{name: "status", method: http.MethodGet, path: "/admin/api/status", wantCall: "status"},
|
|
{name: "routes list", method: http.MethodGet, path: "/admin/api/routes", wantCall: "routes_list"},
|
|
{name: "route item", method: http.MethodPut, path: "/admin/api/routes/play.example", wantCall: "route_item", wantSegment: "play.example"},
|
|
{name: "services list", method: http.MethodGet, path: "/admin/api/services", wantCall: "services_list"},
|
|
{name: "service restart", method: http.MethodPost, path: "/admin/api/services/kcp/restart", wantCall: "service_item", wantSegment: "kcp/restart"},
|
|
{name: "metrics", method: http.MethodGet, path: "/admin/api/metrics", wantCall: "metrics"},
|
|
{name: "users list", method: http.MethodGet, path: "/admin/api/users", wantCall: "users_list"},
|
|
{name: "users create", method: http.MethodPost, path: "/admin/api/users", wantCall: "users_create"},
|
|
{name: "user item", method: http.MethodPatch, path: "/admin/api/users/member", wantCall: "user_item", wantSegment: "member"},
|
|
{name: "audit logs", method: http.MethodGet, path: "/admin/api/audit-logs", wantCall: "audit_logs"},
|
|
{name: "plugin artifacts", method: http.MethodGet, path: "/admin/api/plugin-artifacts", wantCall: "plugin_artifacts"},
|
|
{name: "plugin artifact", method: http.MethodGet, path: "/admin/api/plugin-artifacts/abc", wantCall: "plugin_artifact", wantSegment: "abc"},
|
|
{name: "plugin sources", method: http.MethodGet, path: "/admin/api/plugin-sources", wantCall: "plugin_sources"},
|
|
{name: "plugin builds", method: http.MethodGet, path: "/admin/api/plugin-builds", wantCall: "plugin_builds"},
|
|
{name: "plugin build", method: http.MethodGet, path: "/admin/api/plugin-builds/7", wantCall: "plugin_build", wantSegment: "7"},
|
|
{name: "plugin build retry", method: http.MethodPost, path: "/admin/api/plugin-builds/7/retry", wantCall: "plugin_build", wantSegment: "7/retry"},
|
|
{name: "plugin gc", method: http.MethodGet, path: "/admin/api/plugin-gc", wantCall: "plugin_gc"},
|
|
{name: "plugins list", method: http.MethodGet, path: "/admin/api/plugins", wantCall: "plugins_list"},
|
|
{name: "plugin item", method: http.MethodPut, path: "/admin/api/plugins/upstream-rewrite", wantCall: "plugin_item", wantSegment: "upstream-rewrite"},
|
|
{name: "plugin action", method: http.MethodPost, path: "/admin/api/plugins/upstream-rewrite/enable", wantCall: "plugin_action", wantSegment: "upstream-rewrite/enable"},
|
|
{name: "plugin draining force close", method: http.MethodPost, path: "/admin/api/plugins/mc-auth-proxy/draining/force-close", wantCall: "plugin_draining", wantSegment: "mc-auth-proxy"},
|
|
{name: "plugin dispatch", method: http.MethodGet, path: "/admin/api/plugins/dispatch-plan", wantCall: "plugin_dispatch"},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
var gotCall, gotSegment string
|
|
handler := NewAPIHandler("/admin/api", APIHandlers{
|
|
SetupStatus: recordCall(&gotCall, "setup_status"),
|
|
Setup: recordCall(&gotCall, "setup"),
|
|
Login: recordCall(&gotCall, "login"),
|
|
Logout: recordCall(&gotCall, "logout"),
|
|
Me: recordCall(&gotCall, "me"),
|
|
Status: recordCall(&gotCall, "status"),
|
|
|
|
RoutesList: recordCall(&gotCall, "routes_list"),
|
|
RouteItem: recordSegmentCall(&gotCall, &gotSegment, "route_item"),
|
|
|
|
ServicesList: recordCall(&gotCall, "services_list"),
|
|
ServiceItem: recordSegmentCall(&gotCall, &gotSegment, "service_item"),
|
|
|
|
Metrics: recordCall(&gotCall, "metrics"),
|
|
|
|
UsersList: recordCall(&gotCall, "users_list"),
|
|
UsersCreate: recordCall(&gotCall, "users_create"),
|
|
UserItem: recordSegmentCall(&gotCall, &gotSegment, "user_item"),
|
|
|
|
AuditLogs: recordCall(&gotCall, "audit_logs"),
|
|
|
|
PluginArtifacts: recordCall(&gotCall, "plugin_artifacts"),
|
|
PluginArtifact: recordSegmentCall(&gotCall, &gotSegment, "plugin_artifact"),
|
|
PluginSources: recordCall(&gotCall, "plugin_sources"),
|
|
PluginBuilds: recordCall(&gotCall, "plugin_builds"),
|
|
PluginBuild: recordSegmentCall(&gotCall, &gotSegment, "plugin_build"),
|
|
PluginGC: recordCall(&gotCall, "plugin_gc"),
|
|
PluginsList: recordCall(&gotCall, "plugins_list"),
|
|
PluginItem: recordSegmentCall(&gotCall, &gotSegment, "plugin_item"),
|
|
PluginAction: recordSegmentCall(&gotCall, &gotSegment, "plugin_action"),
|
|
PluginDraining: recordSegmentCall(&gotCall, &gotSegment, "plugin_draining"),
|
|
PluginDispatch: recordCall(&gotCall, "plugin_dispatch"),
|
|
})
|
|
|
|
resp := httptest.NewRecorder()
|
|
req := httptest.NewRequest(tt.method, tt.path, nil)
|
|
handler.ServeHTTP(resp, req)
|
|
if resp.Code != http.StatusNoContent {
|
|
t.Fatalf("status = %d, want %d; body=%s", resp.Code, http.StatusNoContent, resp.Body.String())
|
|
}
|
|
if gotCall != tt.wantCall {
|
|
t.Fatalf("call = %q, want %q", gotCall, tt.wantCall)
|
|
}
|
|
if gotSegment != tt.wantSegment {
|
|
t.Fatalf("segment = %q, want %q", gotSegment, tt.wantSegment)
|
|
}
|
|
if got := resp.Header().Get("Cache-Control"); got != "no-store" {
|
|
t.Fatalf("Cache-Control = %q, want no-store", got)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestNewAPIHandlerWritesNotFound(t *testing.T) {
|
|
handler := NewAPIHandler("/admin/api", APIHandlers{})
|
|
|
|
resp := httptest.NewRecorder()
|
|
req := httptest.NewRequest(http.MethodGet, "/admin/api/auth/login", nil)
|
|
handler.ServeHTTP(resp, req)
|
|
if resp.Code != http.StatusNotFound {
|
|
t.Fatalf("wrong method status = %d, want %d", resp.Code, http.StatusNotFound)
|
|
}
|
|
if strings.TrimSpace(resp.Body.String()) != `{"error":"not found"}` {
|
|
t.Fatalf("wrong method body = %q", resp.Body.String())
|
|
}
|
|
|
|
resp = httptest.NewRecorder()
|
|
req = httptest.NewRequest(http.MethodGet, "/admin/api/missing", nil)
|
|
handler.ServeHTTP(resp, req)
|
|
if resp.Code != http.StatusNotFound {
|
|
t.Fatalf("missing status = %d, want %d", resp.Code, http.StatusNotFound)
|
|
}
|
|
}
|
|
|
|
func recordCall(got *string, call string) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
*got = call
|
|
w.WriteHeader(http.StatusNoContent)
|
|
}
|
|
}
|
|
|
|
func recordSegmentCall(gotCall, gotSegment *string, call string) SegmentHandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request, segment string) {
|
|
*gotCall = call
|
|
*gotSegment = segment
|
|
w.WriteHeader(http.StatusNoContent)
|
|
}
|
|
}
|