Files
dobotai-platform/cmd/dobotai/setup_only_test.go
T

103 lines
3.2 KiB
Go

package main
import (
"context"
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
"time"
"gitea.zheromiku.top/Weknora/dobotai-platform/internal/adminweb"
"gitea.zheromiku.top/Weknora/dobotai-platform/internal/dingtalkconfig"
"gitea.zheromiku.top/Weknora/dobotai-platform/internal/secretstore"
"gitea.zheromiku.top/Weknora/dobotai-platform/internal/settings"
)
type setupRepoStub struct{}
func (setupRepoStub) ActiveDingTalkConfig(context.Context, string) (string, string, bool, error) {
return "", "", false, nil
}
func (setupRepoStub) CandidateDingTalkConfig(context.Context, string) (string, string, error) {
return "", "", nil
}
func (setupRepoStub) SaveDingTalkConfig(context.Context, string, string, string, bool) error {
return nil
}
func (setupRepoStub) MarkDingTalkCandidateFailed(context.Context, string, string, string) error {
return nil
}
func (setupRepoStub) AdministratorCount(context.Context, string) (int, error) { return 0, nil }
func (setupRepoStub) ActiveBindings(context.Context, string) (map[string]settings.ResourceBinding, error) {
return map[string]settings.ResourceBinding{}, nil
}
func (setupRepoStub) CreateBootstrapChallenge(context.Context, string, string, time.Time) error {
return nil
}
func (setupRepoStub) ConfirmBootstrap(context.Context, string) error { return nil }
type setupVerifierStub struct{}
func (setupVerifierStub) Verify(context.Context, string, string) dingtalkconfig.Result {
return dingtalkconfig.Result{}
}
func setupControl(t *testing.T) *adminweb.ControlService {
t.Helper()
secrets, err := secretstore.New(t.TempDir())
if err != nil {
t.Fatal(err)
}
control, err := adminweb.NewControlService("tenant", setupRepoStub{}, secrets, setupVerifierStub{})
if err != nil {
t.Fatal(err)
}
return control
}
func TestSetupOnlyHandlerExposesHealthVersionAndProtectedAdmin(t *testing.T) {
runtime := &settingsRuntime{admin: setupControl(t)}
h, err := newSetupOnlyHandler(runtime, "admin-token")
if err != nil {
t.Fatal(err)
}
req := httptest.NewRequest(http.MethodGet, "/healthz", nil)
resp := httptest.NewRecorder()
h.ServeHTTP(resp, req)
if resp.Code != http.StatusOK {
t.Fatalf("health status=%d", resp.Code)
}
var health map[string]string
if err = json.Unmarshal(resp.Body.Bytes(), &health); err != nil {
t.Fatal(err)
}
if health["status"] != "ok" || health["mode"] != "setup_required" {
t.Fatalf("health=%v", health)
}
resp = httptest.NewRecorder()
h.ServeHTTP(resp, httptest.NewRequest(http.MethodGet, "/version", nil))
if resp.Code != http.StatusOK {
t.Fatalf("version status=%d", resp.Code)
}
resp = httptest.NewRecorder()
h.ServeHTTP(resp, httptest.NewRequest(http.MethodGet, "/admin/settings", nil))
if resp.Code != http.StatusUnauthorized {
t.Fatalf("unauth status=%d", resp.Code)
}
req = httptest.NewRequest(http.MethodGet, "/admin/settings", nil)
req.Header.Set("Authorization", "Bearer admin-token")
resp = httptest.NewRecorder()
h.ServeHTTP(resp, req)
if resp.Code != http.StatusOK {
t.Fatalf("auth status=%d body=%s", resp.Code, resp.Body.String())
}
}
func TestSetupOnlyHandlerRequiresAdminToken(t *testing.T) {
_, err := newSetupOnlyHandler(&settingsRuntime{admin: setupControl(t)}, "")
if err == nil {
t.Fatal("expected token error")
}
}