89 lines
2.8 KiB
Go
89 lines
2.8 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"errors"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"gitea.zheromiku.top/Weknora/dobotai-platform/internal/settings"
|
|
)
|
|
|
|
type bootstrapAdminRepoStub struct {
|
|
administratorCount int
|
|
createdCode string
|
|
createdExpiry time.Time
|
|
confirmCalls int
|
|
}
|
|
|
|
func (r *bootstrapAdminRepoStub) AdministratorCount(context.Context, string) (int, error) {
|
|
return r.administratorCount, nil
|
|
}
|
|
|
|
func (r *bootstrapAdminRepoStub) CreateBootstrapChallenge(_ context.Context, _ string, code string, expiry time.Time) error {
|
|
r.createdCode, r.createdExpiry = code, expiry
|
|
return nil
|
|
}
|
|
|
|
func (r *bootstrapAdminRepoStub) ConfirmBootstrap(context.Context, string) error {
|
|
r.confirmCalls++
|
|
if r.confirmCalls == 1 {
|
|
return settings.ErrBootstrapCandidatePending
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func TestRunBootstrapAdminGeneratesCodeWaitsAndConfirmsCandidate(t *testing.T) {
|
|
now := time.Date(2026, time.September, 10, 8, 0, 0, 0, time.UTC)
|
|
repo := &bootstrapAdminRepoStub{}
|
|
var output bytes.Buffer
|
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
|
defer cancel()
|
|
|
|
err := runBootstrapAdmin(ctx, &output, repo, "tenant-test", bytes.NewReader(make([]byte, 32)), func() time.Time { return now }, time.Millisecond)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if repo.createdCode != "000000" {
|
|
t.Fatalf("code=%q", repo.createdCode)
|
|
}
|
|
if !repo.createdExpiry.Equal(now.Add(10 * time.Minute)) {
|
|
t.Fatalf("expiry=%s", repo.createdExpiry)
|
|
}
|
|
if repo.confirmCalls < 2 {
|
|
t.Fatalf("confirm calls=%d", repo.confirmCalls)
|
|
}
|
|
for _, required := range []string{"/setting 000000", "绑定成功", "super_admin"} {
|
|
if !strings.Contains(output.String(), required) {
|
|
t.Fatalf("output=%q missing %q", output.String(), required)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestRunBootstrapAdminRefusesWhenAdministratorAlreadyExists(t *testing.T) {
|
|
repo := &bootstrapAdminRepoStub{administratorCount: 1}
|
|
err := runBootstrapAdmin(context.Background(), &bytes.Buffer{}, repo, "tenant-test", bytes.NewReader(make([]byte, 32)), time.Now, time.Millisecond)
|
|
if err == nil || !strings.Contains(err.Error(), "already exists") {
|
|
t.Fatalf("err=%v", err)
|
|
}
|
|
if repo.createdCode != "" || repo.confirmCalls != 0 {
|
|
t.Fatalf("repo mutated: %+v", repo)
|
|
}
|
|
}
|
|
|
|
func TestRunBootstrapAdminPropagatesChallengeCreationFailure(t *testing.T) {
|
|
repo := &bootstrapAdminRepoStub{}
|
|
original := createBootstrapChallenge
|
|
createBootstrapChallenge = func(context.Context, bootstrapAdminRepository, string, string, time.Time) error {
|
|
return errors.New("database unavailable")
|
|
}
|
|
t.Cleanup(func() { createBootstrapChallenge = original })
|
|
|
|
err := runBootstrapAdmin(context.Background(), &bytes.Buffer{}, repo, "tenant-test", bytes.NewReader(make([]byte, 32)), time.Now, time.Millisecond)
|
|
if err == nil || !strings.Contains(err.Error(), "database unavailable") {
|
|
t.Fatalf("err=%v", err)
|
|
}
|
|
}
|