Files
tunnel/internal/server/admin_test.go
T

117 lines
3.2 KiB
Go

package server
import (
"encoding/json"
"net/http"
"net/http/httptest"
"strings"
"testing"
"time"
)
func TestAdminOverview(t *testing.T) {
store, err := OpenStore("")
if err != nil {
t.Fatal(err)
}
api := &API{
Store: store, Hub: NewHub(store), Domain: "opentunnel.test",
AdminToken: "admin-secret", StartedAt: time.Now().Add(-90 * time.Second), Version: "test",
}
srv := httptest.NewServer(api)
defer srv.Close()
if _, _, err := store.createTunnel("opentunnel.test"); err != nil {
t.Fatal(err)
}
// no token configured → 503
noToken := &API{Store: store, Hub: NewHub(store), Domain: "opentunnel.test", StartedAt: time.Now()}
noTokenSrv := httptest.NewServer(noToken)
defer noTokenSrv.Close()
resp, err := http.Get(noTokenSrv.URL + "/api/admin/overview")
if err != nil {
t.Fatal(err)
}
if resp.StatusCode != 503 {
t.Errorf("unconfigured admin token: got %d, want 503", resp.StatusCode)
}
resp.Body.Close()
// missing and wrong token → 401
for _, header := range []string{"", "Bearer nope"} {
req, _ := http.NewRequest("GET", srv.URL+"/api/admin/overview", nil)
if header != "" {
req.Header.Set("Authorization", header)
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
t.Fatal(err)
}
if resp.StatusCode != 401 {
t.Errorf("auth %q: got %d, want 401", header, resp.StatusCode)
}
resp.Body.Close()
}
// correct token → 200 with the tunnel and server info
req, _ := http.NewRequest("GET", srv.URL+"/api/admin/overview", nil)
req.Header.Set("Authorization", "Bearer admin-secret")
resp, err = http.DefaultClient.Do(req)
if err != nil {
t.Fatal(err)
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
t.Fatalf("admin overview: got %d, want 200", resp.StatusCode)
}
var overview adminOverview
if err := json.NewDecoder(resp.Body).Decode(&overview); err != nil {
t.Fatal(err)
}
if overview.Server.Domain != "opentunnel.test" || overview.Server.Version != "test" {
t.Errorf("server info: %+v", overview.Server)
}
if overview.Server.UptimeSeconds < 60 {
t.Errorf("uptime: %d", overview.Server.UptimeSeconds)
}
if overview.Totals.Tunnels != 1 || overview.Totals.Online != 0 {
t.Errorf("totals: %+v", overview.Totals)
}
if len(overview.Tunnels) != 1 || !strings.HasSuffix(overview.Tunnels[0].Hostname, ".opentunnel.test") {
t.Errorf("tunnels: %+v", overview.Tunnels)
}
if overview.Tunnels[0].State != "offline" {
t.Errorf("tunnel state: %q", overview.Tunnels[0].State)
}
if overview.CA.Expires == "" {
t.Error("CA expiry missing")
}
}
func TestDashboardPage(t *testing.T) {
store, err := OpenStore("")
if err != nil {
t.Fatal(err)
}
api := &API{Store: store, Hub: NewHub(store), Domain: "opentunnel.test", StartedAt: time.Now()}
srv := httptest.NewServer(api)
defer srv.Close()
for _, path := range []string{"/", "/admin"} {
resp, err := http.Get(srv.URL + path)
if err != nil {
t.Fatal(err)
}
body := make([]byte, 512)
n, _ := resp.Body.Read(body)
resp.Body.Close()
if resp.StatusCode != 200 || !strings.Contains(resp.Header.Get("Content-Type"), "text/html") {
t.Errorf("%s: got %d %q", path, resp.StatusCode, resp.Header.Get("Content-Type"))
}
if !strings.Contains(string(body[:n]), "tunneld admin") {
t.Errorf("%s: unexpected body", path)
}
}
}