package api import ( "context" "database/sql" "encoding/json" "net/http" "os" "testing" accountdomain "git.ipao.vip/rogee/creator-hub/internal/account" "git.ipao.vip/rogee/creator-hub/internal/creator" hub "git.ipao.vip/rogee/creator-hub/internal/environment" "github.com/gofiber/fiber/v3" ) func maintenanceAccountFixture(t *testing.T, ctx context.Context, store *accountdomain.Store) string { t.Helper() id := accountdomain.NewAccountID() account := accountdomain.Account{ID: id, Name: "已有账号", Platform: "douyin", PlatformAccountKey: id, Tags: []string{}, CredentialReference: accountdomain.CredentialReference{ID: id + "-cookies", Provider: "os_keyring"}, CredentialKey: "creatorhub/" + id + "/cookies", RuntimeStatus: "paused", Version: 1} if err := store.CreateAccount(ctx, account, &testCredentialBridge{values: map[string]string{}}); err != nil { t.Fatal(err) } return id } func TestEnvironmentCreationDoesNotCreatePlatformAccount(t *testing.T) { databaseURL := os.Getenv("CREATORHUB_POSTGRES_TEST_URL") if databaseURL == "" { t.Skip("set CREATORHUB_POSTGRES_TEST_URL") } databaseURL = isolatedControlPlaneDatabaseURL(t, databaseURL) ctx := context.Background() hs, err := hub.Open(ctx, databaseURL) if err != nil { t.Fatal(err) } t.Cleanup(func() { _ = hs.Close() }) cs, err := creator.Open(ctx, databaseURL) if err != nil { t.Fatal(err) } t.Cleanup(func() { _ = cs.Close() }) db, err := sql.Open("pgx", databaseURL) if err != nil { t.Fatal(err) } t.Cleanup(func() { _ = db.Close() }) app := fiber.New() registerEnvironmentLoginRoutes(app, cs, hs) response := do(app, http.MethodPost, "/api/creator/environments", `{"gateway":"gw-main"}`) if response.Code != http.StatusNotFound { t.Fatalf("missing gateway: %d %s", response.Code, response.Body.String()) } if _, err := hs.CreateGateway(ctx, "gw-main", "http://127.0.0.1:28187", "test-token-environment"); err != nil { t.Fatal(err) } response = do(app, http.MethodPost, "/api/creator/environments", `{"gateway":"gw-main","fingerprint":{"platform":"windows","lang":"zh-CN","timezone":"Asia/Shanghai"}}`) if response.Code != http.StatusCreated { t.Fatalf("create: %d %s", response.Code, response.Body.String()) } var env hub.EnvironmentContext if err := json.Unmarshal(response.Body.Bytes(), &env); err != nil { t.Fatal(err) } if env.AccountID != "" || env.ProfileID != env.Alias || env.Fingerprint.Seed < 1001 || env.Fingerprint.Lang != "zh-CN" { t.Fatalf("unbound environment: %#v", env) } var count int if err := db.QueryRowContext(ctx, `SELECT count(*) FROM social_account`).Scan(&count); err != nil || count != 0 { t.Fatalf("creation made placeholder account: %d %v", count, err) } pending, err := hs.ListPendingEnvironments(ctx) if err != nil || len(pending) != 1 { t.Fatalf("pending: %v %v", pending, err) } for _, body := range []string{`{"gateway":"gw-main","name":"手填昵称"}`, `{"gateway":"gw-main","platform_account_key":"123"}`, `{"gateway":"gw-main","fingerprint":{"platform":"android"}}`, `{"gateway":"gw-main","fingerprint":{"seed":42}}`, `{"gateway":"gw-main","fingerprint":{"proxy_server":"http://invalid:8080"}}`} { if response := do(app, http.MethodPost, "/api/creator/environments", body); response.Code != http.StatusBadRequest { t.Fatalf("invalid input accepted: %s %d %s", body, response.Code, response.Body.String()) } } result, err := cs.RecordVerifiedEnvironmentLogin(ctx, env.Alias, creator.PlatformIdentity{UID: "99491952055", Nickname: "同步昵称", DouyinNumber: "1004291301", AvatarURL: "https://example.com/avatar.jpg"}) if err != nil { t.Fatal(err) } bound, err := hs.GetEnvironmentContext(ctx, env.Alias) if err != nil || bound.AccountID != result.AccountID || bound.ProfileID != env.ProfileID || bound.Fingerprint.Seed != env.Fingerprint.Seed { t.Fatalf("binding replaced browser: %#v %v", bound, err) } pending, err = hs.ListPendingEnvironments(ctx) if err != nil || len(pending) != 0 { t.Fatalf("bound env still pending: %v %v", pending, err) } RegisterAccountRoutes(app, nil, nil, nil) if response := do(app, http.MethodPost, "/api/phase-a/accounts", `{"name":"废弃入口"}`); response.Code != http.StatusMethodNotAllowed { t.Fatalf("old creation path remains: %d", response.Code) } }