Files
creator-hub/internal/controlplane/api/environment_login_test.go
T

119 lines
4.2 KiB
Go

package api
import (
"context"
"encoding/json"
"net/http"
"net/http/httptest"
"os"
"strings"
"testing"
"git.ipao.vip/rogee/creator-hub/internal/creator"
hub "git.ipao.vip/rogee/creator-hub/internal/environment"
"github.com/gofiber/fiber/v3"
)
func TestPendingEnvironmentLoginRoutesKeepBrowserIdentity(t *testing.T) {
raw := os.Getenv("CREATORHUB_POSTGRES_TEST_URL")
if raw == "" {
t.Skip("set CREATORHUB_POSTGRES_TEST_URL")
}
dbURL := isolatedControlPlaneDatabaseURL(t, raw)
ctx := context.Background()
hs, err := hub.Open(ctx, dbURL)
if err != nil {
t.Fatal(err)
}
defer hs.Close()
cs, err := creator.Open(ctx, dbURL)
if err != nil {
t.Fatal(err)
}
defer cs.Close()
alias := ""
running := false
logged := false
creates := 0
gateway := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
runtime := map[string]any{"id": "login-runtime", "alias": alias, "state": "running", "binding_version": 1, "network_id": "login-network", "node_id": "login-node", "proxy_ready": true}
switch {
case r.Method == http.MethodGet && r.URL.Path == "/v1/browsers":
items := []map[string]any{}
if running {
items = append(items, runtime)
}
json.NewEncoder(w).Encode(items)
case r.Method == http.MethodGet && r.URL.Path == "/v1/browsers/"+alias:
if !running {
w.WriteHeader(http.StatusNotFound)
return
}
json.NewEncoder(w).Encode(runtime)
case r.Method == http.MethodPost && r.URL.Path == "/v1/browsers":
var body map[string]any
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
t.Error(err)
}
if body["profile_id"] != alias || body["alias"] != alias {
t.Errorf("unstable browser identity: %#v", body)
}
running = true
creates++
w.WriteHeader(http.StatusCreated)
json.NewEncoder(w).Encode(runtime)
case strings.HasSuffix(r.URL.Path, "/douyin/identity"):
if !logged {
json.NewEncoder(w).Encode(map[string]string{"status": "manual_login", "reason": "awaiting_login"})
return
}
json.NewEncoder(w).Encode(creator.PlatformIdentity{UID: "99491952055", Nickname: "平台昵称", AvatarURL: "https://example.com/avatar.jpg", DouyinNumber: "1004291301", SecUID: "MS4w-test"})
case strings.HasSuffix(r.URL.Path, "/douyin/login-qr"):
json.NewEncoder(w).Encode(map[string]any{"content_type": "image/png", "body_base64": "aGk=", "qr_detected": true})
default:
t.Errorf("unexpected native request %s %s", r.Method, r.URL.Path)
http.NotFound(w, r)
}
}))
defer gateway.Close()
if _, err := hs.CreateGateway(ctx, "login-gw", gateway.URL, "test-token-login"); err != nil {
t.Fatal(err)
}
env, err := hs.CreateStandaloneEnv(ctx, "login-gw", hub.Fingerprint{})
if err != nil {
t.Fatal(err)
}
alias = env.Alias
app := fiber.New()
registerEnvironmentLoginRoutes(app, cs, hs)
route := "/api/creator/environments/" + alias
for _, suffix := range []string{"verify", "login-qr"} {
response := do(app, http.MethodPost, route+"/"+suffix, `{}`)
if response.Code != http.StatusOK {
t.Fatalf("%s: %d %s", suffix, response.Code, response.Body.String())
}
}
pending, err := hs.ListPendingEnvironments(ctx)
if err != nil || len(pending) != 1 || pending[0].ID != env.ID || env.ID < 1 {
t.Fatalf("pending browser created account or lost its ordering ID: %v %v", pending, err)
}
logged = true
response := do(app, http.MethodPost, route+"/verify", `{}`)
if response.Code != http.StatusOK {
t.Fatalf("verify: %d %s", response.Code, response.Body.String())
}
var result creator.LoginResult
if err := json.Unmarshal(response.Body.Bytes(), &result); err != nil || result.AccountID == "" || result.Status != "logged_in" {
t.Fatalf("login response: %#v %v", result, err)
}
bound, err := hs.GetEnvironmentContext(ctx, alias)
if err != nil || bound.AccountID != result.AccountID || bound.RuntimeID != "login-runtime" || bound.ProfileID != alias || bound.Fingerprint.Seed != env.Fingerprint.Seed || bound.ID != env.ID {
t.Fatalf("binding changed browser: %#v %v", bound, err)
}
response = do(app, http.MethodPost, route+"/verify", `{}`)
if response.Code != http.StatusOK || creates != 1 {
t.Fatalf("repeat login recreated browser: creates=%d %d %s", creates, response.Code, response.Body.String())
}
}