package api import ( "context" "encoding/json" "net/http" "os" "testing" "git.ipao.vip/rogee/creator-hub/internal/creator" hub "git.ipao.vip/rogee/creator-hub/internal/environment" "github.com/gofiber/fiber/v3" ) func TestCreatePendingEnvironmentUsesSelectedGateway(t *testing.T) { raw := os.Getenv("CREATORHUB_POSTGRES_TEST_URL") if raw == "" { t.Skip("set CREATORHUB_POSTGRES_TEST_URL") } ctx := context.Background() dbURL := isolatedControlPlaneDatabaseURL(t, raw) 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() for _, name := range []string{"gw-a", "gw-b"} { if _, err := hs.CreateGateway(ctx, name, "http://"+name+":9100", "test-gateway-token-"+name); err != nil { t.Fatal(err) } } app := fiber.New() registerEnvironmentLoginRoutes(app, cs, hs) for _, input := range []struct { body string status int }{ {`{"gateway":"gw-b","fingerprint":{"timezone":"Asia/Shanghai"}}`, http.StatusCreated}, {`{"gateway":"gw-a"}`, http.StatusCreated}, {`{}`, http.StatusBadRequest}, {`{"gateway":""}`, http.StatusBadRequest}, {`{"gateway":"missing"}`, http.StatusNotFound}, {`{"gateway":"bad gateway"}`, http.StatusBadRequest}, {`{"gateway":"gw-a","fingerprint":{"seed":123}}`, http.StatusBadRequest}, {`{"gateway":"gw-a","fingerprint":{"proxy_server":"http://example.com"}}`, http.StatusBadRequest}, {`{"gateway":"gw-a","fingerprint":{"hardware_concurrency":-1}}`, http.StatusBadRequest}, {`{`, http.StatusBadRequest}, } { t.Run(input.body, func(t *testing.T) { response := do(app, http.MethodPost, "/api/creator/environments", input.body) if response.Code != input.status { t.Fatalf("status=%d want=%d: %s", response.Code, input.status, response.Body.String()) } if input.status != http.StatusCreated { return } var env hub.EnvironmentContext if err := json.Unmarshal(response.Body.Bytes(), &env); err != nil { t.Fatal(err) } var payload struct { Gateway string `json:"gateway"` Fingerprint hub.Fingerprint `json:"fingerprint"` } if err := json.Unmarshal([]byte(input.body), &payload); err != nil { t.Fatal(err) } if env.Gateway != payload.Gateway || env.Alias == "" || env.ProfileID != env.Alias || env.Fingerprint.Seed == 0 || env.AccountID != "" || env.Fingerprint.Timezone != payload.Fingerprint.Timezone { t.Fatalf("invalid pending environment: %#v", env) } stored, err := hs.GetEnvironmentContext(ctx, env.Alias) if err != nil || stored.Gateway != payload.Gateway { t.Fatalf("selected gateway not stored: %#v %v", stored, err) } }) } pending, err := hs.ListPendingEnvironments(ctx) if err != nil || len(pending) != 2 { t.Fatalf("invalid pending list: %#v %v", pending, err) } if pending[0].Fingerprint.Seed == pending[1].Fingerprint.Seed { t.Fatal("environments must have independent fingerprint seeds") } profiles, err := cs.ListAccountProfiles(ctx) if err != nil || len(profiles) != 0 { t.Fatalf("creation wrote placeholder account: %#v %v", profiles, err) } }