package main import ( "bytes" "context" "strings" "testing" ) func TestBatchImportCLI(t *testing.T) { t.Parallel() t.Run("parses subscription request and confirm timeout", func(t *testing.T) { t.Parallel() req, err := parseBatchImportCLIArgs([]string{ "--host-id", "host-1", "--entry", "https://kimi.example.com/v1,sk-kimi,kimi-k2.6|kimi-2.6", "--mode", "strict", "--access-mode", "subscription", "--subscription-users", "u1,u2", "--subscription-days", "30", "--confirm-timeout", "15s", }) if err != nil { t.Fatalf("parseBatchImportCLIArgs() error = %v", err) } if req.HostID != "host-1" { t.Fatalf("HostID = %q, want host-1", req.HostID) } if req.ConfirmWaitTimeoutSec != 15 { t.Fatalf("ConfirmWaitTimeoutSec = %d, want 15", req.ConfirmWaitTimeoutSec) } if len(req.SubscriptionUsers) != 2 || req.SubscriptionUsers[0] != "u1" || req.SubscriptionUsers[1] != "u2" { t.Fatalf("SubscriptionUsers = %#v, want [u1 u2]", req.SubscriptionUsers) } if len(req.Entries) != 1 { t.Fatalf("Entries length = %d, want 1", len(req.Entries)) } if req.Entries[0].BaseURL != "https://kimi.example.com/v1" { t.Fatalf("Entries[0].BaseURL = %q, want kimi url", req.Entries[0].BaseURL) } if len(req.Entries[0].RequestedModels) != 2 { t.Fatalf("Entries[0].RequestedModels = %#v, want 2 models", req.Entries[0].RequestedModels) } }) t.Run("subscription requires subscription fields", func(t *testing.T) { t.Parallel() _, err := parseBatchImportCLIArgs([]string{ "--host-id", "host-1", "--entry", "https://kimi.example.com/v1,sk-kimi", "--mode", "strict", "--access-mode", "subscription", }) if err == nil { t.Fatal("parseBatchImportCLIArgs() error = nil, want validation error") } if !strings.Contains(err.Error(), "--subscription-users is required") { t.Fatalf("parseBatchImportCLIArgs() error = %v, want subscription-users validation", err) } }) t.Run("self service requires probe api key", func(t *testing.T) { t.Parallel() _, err := parseBatchImportCLIArgs([]string{ "--host-id", "host-1", "--entry", "https://deepseek.example.com/v1,sk-deepseek", "--mode", "partial", "--access-mode", "self_service", }) if err == nil { t.Fatal("parseBatchImportCLIArgs() error = nil, want validation error") } if !strings.Contains(err.Error(), "--probe-api-key is required") { t.Fatalf("parseBatchImportCLIArgs() error = %v, want probe-api-key validation", err) } }) t.Run("execute writes run id and result page", func(t *testing.T) { t.Parallel() var output bytes.Buffer batchImportCalled := false err := execute(context.Background(), &output, []string{ "batch-import", "--host-id", "host-1", "--entry", "https://kimi.example.com/v1,sk-kimi", "--mode", "strict", "--access-mode", "self_service", "--probe-api-key", "gateway-key", "--confirm-timeout", "15s", }, nil, nil, nil, nil, nil, nil, nil, func(_ context.Context, req batchImportCLIRequest) (batchImportCLIResult, error) { batchImportCalled = true if req.HostID != "host-1" { t.Fatalf("HostID = %q, want host-1", req.HostID) } if req.AccessMode != "self_service" { t.Fatalf("AccessMode = %q, want self_service", req.AccessMode) } if req.ProbeAPIKey != "gateway-key" { t.Fatalf("ProbeAPIKey = %q, want gateway-key", req.ProbeAPIKey) } if req.ConfirmWaitTimeoutSec != 15 { t.Fatalf("ConfirmWaitTimeoutSec = %d, want 15", req.ConfirmWaitTimeoutSec) } return batchImportCLIResult{ RunID: "run_20260522_0001", ResultPage: "/batch-import/runs/run_20260522_0001", }, nil }) if err != nil { t.Fatalf("execute() batch-import error = %v", err) } if !batchImportCalled { t.Fatal("execute() did not invoke batchImport") } got := output.String() if !strings.Contains(got, "run_id=run_20260522_0001") || !strings.Contains(got, "result_page=/batch-import/runs/run_20260522_0001") { t.Fatalf("execute() batch-import output = %q, want run summary", got) } }) }