package helpers import ( "bytes" "context" "encoding/json" "errors" "fmt" "io" "os" "strings" "testing" "github.com/DingTalk-Real-AI/dingtalk-workspace-cli/pkg/edition" "github.com/spf13/cobra" ) func driveDepthTestCmd() *cobra.Command { cmd := &cobra.Command{Use: "list"} cmd.Flags().String("cursor", "", "") cmd.Flags().String("next-token", "", "") cmd.Flags().Int("limit", 0, "") cmd.Flags().Int("max", 0, "") return cmd } func TestCrossPlatformCoverageDriveDepthCancelledError(t *testing.T) { err := &driveDepthCancelledError{} if err.Error() != driveDepthCancelledMsg || err.RawStderr() != driveDepthCancelledMsg { t.Fatalf("messages = %q/%q", err.Error(), err.RawStderr()) } if err.ExitCode() != 130 { t.Fatalf("ExitCode = %d, want 130", err.ExitCode()) } } func TestCrossPlatformCoverageValidateDriveListDepth(t *testing.T) { newCmd := func() *cobra.Command { return driveDepthTestCmd() } if err := validateDriveListDepth(newCmd(), 0); err == nil { t.Fatal("depth 0 returned nil") } if err := validateDriveListDepth(newCmd(), driveDepthMax+1); err == nil { t.Fatal("depth above max returned nil") } shallow := newCmd() _ = shallow.Flags().Set("cursor", "c1") _ = shallow.Flags().Set("limit", "5") if err := validateDriveListDepth(shallow, 1); err != nil { t.Fatalf("depth 1 with cursor/limit returned %v", err) } withCursor := newCmd() _ = withCursor.Flags().Set("cursor", "c1") if err := validateDriveListDepth(withCursor, 2); err == nil { t.Fatal("depth 2 with cursor returned nil") } withNextToken := newCmd() _ = withNextToken.Flags().Set("next-token", "t1") if err := validateDriveListDepth(withNextToken, 2); err == nil { t.Fatal("depth 2 with next-token returned nil") } withLimit := newCmd() _ = withLimit.Flags().Set("limit", "5") if err := validateDriveListDepth(withLimit, 2); err == nil { t.Fatal("depth 2 with limit returned nil") } withMax := newCmd() _ = withMax.Flags().Set("max", "5") if err := validateDriveListDepth(withMax, 2); err == nil { t.Fatal("depth 2 with max returned nil") } if err := validateDriveListDepth(newCmd(), 2); err != nil { t.Fatalf("depth 2 clean returned %v", err) } if err := validateDriveListDepth(newCmd(), driveDepthMax); err != nil { t.Fatalf("depth max clean returned %v", err) } } func TestCrossPlatformCoverageDriveDepthRoutesBuildArgs(t *testing.T) { pan := newDrivePanDepthRoute() args := pan.buildArgs(map[string]any{"spaceId": "s1"}, "folder1", "tok") if args["maxResults"] != float64(driveDepthPageSize) || args["spaceId"] != "s1" || args["parentId"] != "folder1" || args["nextToken"] != "tok" { t.Fatalf("pan args = %#v", args) } empty := pan.buildArgs(nil, "", "") if _, ok := empty["parentId"]; ok { t.Fatalf("pan empty folder args = %#v", empty) } if _, ok := empty["nextToken"]; ok { t.Fatalf("pan empty token args = %#v", empty) } if id := pan.itemID(map[string]any{"fileId": "f1"}); id != "f1" { t.Fatalf("pan itemID = %q", id) } if id := pan.itemID(map[string]any{}); id != "" { t.Fatalf("pan missing itemID = %q", id) } doc := newDocDepthRoute() dargs := doc.buildArgs(map[string]any{"workspaceId": "w1"}, "node1", "pt") if dargs["pageSize"] != float64(docDepthPageSize) || dargs["workspaceId"] != "w1" || dargs["folderId"] != "node1" || dargs["pageToken"] != "pt" { t.Fatalf("doc args = %#v", dargs) } dempty := doc.buildArgs(nil, "", "") if _, ok := dempty["folderId"]; ok { t.Fatalf("doc empty folder args = %#v", dempty) } if id := doc.itemID(map[string]any{"nodeId": "n1"}); id != "n1" { t.Fatalf("doc itemID = %q", id) } if id := doc.itemID(map[string]any{}); id != "" { t.Fatalf("doc missing itemID = %q", id) } } func TestCrossPlatformCoverageParseDriveDepthPage(t *testing.T) { if items, next, hasMore := parseDriveDepthPage(`{invalid`); items != nil || next != "" || hasMore { t.Fatalf("invalid JSON = %#v %q %v", items, next, hasMore) } if items, _, _ := parseDriveDepthPage(`{"foo":1}`); items != nil { t.Fatalf("missing items key = %#v", items) } items, next, hasMore := parseDriveDepthPage(`{"items":[{"name":"a"},42],"nextToken":"t","hasMore":true}`) if len(items) != 1 || items[0]["name"] != "a" || next != "t" || !hasMore { t.Fatalf("top-level items = %#v %q %v", items, next, hasMore) } items, next, _ = parseDriveDepthPage(`{"result":{"dentryList":[{"name":"b"}],"nextToken":"t2"}}`) if len(items) != 1 || items[0]["name"] != "b" || next != "t2" { t.Fatalf("result dentryList = %#v %q", items, next) } if items, _, _ := parseDriveDepthPage(`{"result":{"other":1}}`); items != nil { t.Fatalf("result without items = %#v", items) } } func TestCrossPlatformCoverageDriveDepthListItemsKey(t *testing.T) { if k := driveDepthListItemsKey(map[string]any{"items": []any{}}); k != "items" { t.Fatalf("items key = %q", k) } if k := driveDepthListItemsKey(map[string]any{"dentryList": []any{1}}); k != "dentryList" { t.Fatalf("dentryList key = %q", k) } if k := driveDepthListItemsKey(map[string]any{"items": nil}); k != "" { t.Fatalf("nil items key = %q", k) } if k := driveDepthListItemsKey(map[string]any{}); k != "" { t.Fatalf("missing key = %q", k) } } func TestCrossPlatformCoverageParseDocDepthPage(t *testing.T) { if items, next, hasMore := parseDocDepthPage(`{bad`); items != nil || next != "" || hasMore { t.Fatalf("invalid JSON = %#v %q %v", items, next, hasMore) } items, next, hasMore := parseDocDepthPage(`{"nodes":[{"name":"a"},"x"],"nextPageToken":"nt","hasMore":true}`) if len(items) != 1 || next != "nt" || !hasMore { t.Fatalf("nodes = %#v %q %v", items, next, hasMore) } } func TestCrossPlatformCoverageMatchDriveNamePattern(t *testing.T) { if !matchDriveNamePattern("anything", "") { t.Fatal("empty pattern should match") } if !matchDriveNamePattern("report.xlsx", "*.xlsx") || matchDriveNamePattern("report.csv", "*.xlsx") { t.Fatal("glob match failed") } if !matchDriveNamePattern("weekly-report.xlsx", "report") || matchDriveNamePattern("a.txt", "report") { t.Fatal("substring wrap failed") } if !matchDriveNamePattern("a[b", "[") { t.Fatal("invalid pattern should fall back to substring") } } func TestCrossPlatformCoverageDriveDepthItemClassifiers(t *testing.T) { if !isDriveDepthFolder(map[string]any{"type": "FOLDER"}) { t.Fatal("type FOLDER not detected") } if !isDriveDepthFolder(map[string]any{"dentryType": "folder"}) { t.Fatal("dentryType folder not detected") } if isDriveDepthFolder(map[string]any{"type": "FILE"}) || isDriveDepthFolder(map[string]any{}) { t.Fatal("non-folder detected as folder") } if !isDocDepthFolder(map[string]any{"nodeType": "Folder"}) { t.Fatal("doc folder not detected") } if isDocDepthFolder(map[string]any{"nodeType": "doc"}) { t.Fatal("doc detected as folder") } if id := driveDepthItemID(map[string]any{"fileId": "f"}); id != "f" { t.Fatalf("fileId = %q", id) } if id := driveDepthItemID(map[string]any{"nodeId": "n"}); id != "n" { t.Fatalf("nodeId = %q", id) } if id := driveDepthItemID(map[string]any{"fileId": ""}); id != "" { t.Fatalf("empty = %q", id) } } func TestCrossPlatformCoverageDriveDepthUnrecoverable(t *testing.T) { for _, code := range []string{CodeAuthTokenExpired, CodeAuthNotConfigured, CodeNetworkTimeout, CodeNetworkUnreachable} { if !driveDepthUnrecoverable(&CLIError{Code: code}) { t.Fatalf("%s not unrecoverable", code) } } if driveDepthUnrecoverable(&CLIError{Code: CodeMCPToolError}) { t.Fatal("tool error marked unrecoverable") } if driveDepthUnrecoverable(errors.New("plain")) { t.Fatal("plain error marked unrecoverable") } } func TestCrossPlatformCoverageDriveDepthErrorCode(t *testing.T) { if c := driveDepthErrorCode(errors.New("plain")); c != "" { t.Fatalf("plain = %q", c) } if c := driveDepthErrorCode(&CLIError{Message: "not json"}); c != "" { t.Fatalf("non-JSON = %q", c) } for _, tc := range []struct{ body, want string }{ {`{"errorCode":"a.b"}`, "a.b"}, {`{"error_code":"c.d"}`, "c.d"}, {`{"code":"e.f"}`, "e.f"}, {`{"errorCode":""}`, ""}, } { if c := driveDepthErrorCode(&CLIError{Message: tc.body}); c != tc.want { t.Fatalf("%s = %q, want %q", tc.body, c, tc.want) } } } func TestCrossPlatformCoverageClassifyDriveDepthReason(t *testing.T) { if r := classifyDriveDepthReason(driveDepthRateLimitedCode); r != "rate_limited" { t.Fatalf("rate limit = %q", r) } if r := classifyDriveDepthReason("forbidden.noPermission"); r != "permission_denied" { t.Fatalf("forbidden = %q", r) } if r := classifyDriveDepthReason("other.x"); r != "api_error" { t.Fatalf("other = %q", r) } } func TestCrossPlatformCoverageDriveDepthErrorMessage(t *testing.T) { if m := driveDepthErrorMessage(&CLIError{Message: `{"errorMsg":"boom"}`}); m != "boom" { t.Fatalf("errorMsg = %q", m) } if m := driveDepthErrorMessage(&CLIError{Message: `{"message":"m2"}`}); m != "m2" { t.Fatalf("message = %q", m) } if m := driveDepthErrorMessage(&CLIError{Message: "raw text"}); m != "raw text" { t.Fatalf("raw = %q", m) } if m := driveDepthErrorMessage(errors.New("plain boom")); m != "plain boom" { t.Fatalf("plain = %q", m) } } func TestCrossPlatformCoverageNewDriveDepthError(t *testing.T) { folder := driveDepthFolder{id: "f1", name: "folder one", depth: 2} derr := newDriveDepthError(folder, &CLIError{Code: CodeMCPToolError, Message: `{"errorCode":"forbidden.x","errorMsg":"denied"}`}) if derr.Depth != 2 || derr.FolderID != "f1" || derr.FolderName != "folder one" || derr.Reason != "permission_denied" || derr.Message != "denied" { t.Fatalf("driveDepthError = %#v", derr) } } type failingWriter struct{} func (failingWriter) Write([]byte) (int, error) { return 0, errors.New("write failed") } func installDepthCaller(t *testing.T, caller *scriptedToolCaller) *bytes.Buffer { t.Helper() installScriptedCaller(t, caller) buf := &bytes.Buffer{} deps.Out.w = buf return buf } func decodeDepthResult(t *testing.T, buf *bytes.Buffer) map[string]any { t.Helper() var out map[string]any if err := json.Unmarshal(buf.Bytes(), &out); err != nil { t.Fatalf("output is not JSON: %v\n%s", err, buf.String()) } return out } func TestCrossPlatformCoverageEmitDriveDepthResult(t *testing.T) { out := installDepthCaller(t, &scriptedToolCaller{}) items := []map[string]any{ {"fileName": "b-file.xlsx", "rel_path": "b", "depth": 1, "fileId": "f2"}, {"name": "a-file.xlsx", "rel_path": "a", "depth": 2, "fileId": "f1"}, {"name": "skip-me.csv", "rel_path": "c", "depth": 1, "fileId": "f3"}, } if err := emitDriveDepthResult(items, nil, false, "*.xlsx", 0, 0, newDrivePanDepthRoute(), driveListFilter{}); err != nil { t.Fatal(err) } result := decodeDepthResult(t, out) got := result["items"].([]any) if len(got) != 2 { t.Fatalf("filtered items = %#v", got) } if got[0].(map[string]any)["rel_path"] != "a" || got[1].(map[string]any)["rel_path"] != "b" { t.Fatalf("sort order = %#v", got) } if result["maxDepth"] != float64(2) { t.Fatalf("maxDepth = %#v", result["maxDepth"]) } if result["truncated"] != false { t.Fatalf("truncated = %#v", result["truncated"]) } out.Reset() if err := emitDriveDepthResult(nil, nil, false, "", 0, 0, newDrivePanDepthRoute(), driveListFilter{}); err != nil { t.Fatal(err) } result = decodeDepthResult(t, out) if items, ok := result["items"].([]any); !ok || len(items) != 0 { t.Fatalf("nil items = %#v", result["items"]) } samePath := []map[string]any{ {"name": "dup", "rel_path": "p/dup", "fileId": "z9"}, {"name": "dup", "rel_path": "p/dup", "fileId": "a1"}, } out.Reset() if err := emitDriveDepthResult(samePath, nil, false, "", 0, 0, newDrivePanDepthRoute(), driveListFilter{}); err != nil { t.Fatal(err) } got = decodeDepthResult(t, out)["items"].([]any) if got[0].(map[string]any)["fileId"] != "a1" { t.Fatalf("tie-break order = %#v", got) } deps.Out.w = failingWriter{} if err := emitDriveDepthResult(nil, nil, false, "", 0, 0, newDrivePanDepthRoute(), driveListFilter{}); err == nil { t.Fatal("failing writer returned nil") } } func TestCrossPlatformCoveragePrintDriveDepthDryRun(t *testing.T) { jsonOut := installDepthCaller(t, &scriptedToolCaller{format: "json", dry: true}) if err := printDriveDepthDryRun(newDrivePanDepthRoute(), map[string]any{"spaceId": "s1"}, 3); err != nil { t.Fatal(err) } var payload map[string]any if err := json.Unmarshal(jsonOut.Bytes(), &payload); err != nil { t.Fatalf("json dry-run output: %v", err) } if payload["dry_run"] != true || payload["tool"] != "list_files" || payload["maxDepth"] != float64(3) { t.Fatalf("json dry-run = %#v", payload) } installDepthCaller(t, &scriptedToolCaller{format: "table", dry: true}) if err := printDriveDepthDryRun(newDocDepthRoute(), map[string]any{"workspaceId": "w1"}, 2); err != nil { t.Fatal(err) } } func useDriveDepthArgs(t *testing.T) { t.Helper() old := os.Args os.Args = []string{"dws", "drive", "list", "--depth", "2"} t.Cleanup(func() { os.Args = old }) } func runDepthBFS(t *testing.T, caller *scriptedToolCaller, route driveDepthRoute, root string, maxDepth int, pattern string) (map[string]any, error) { t.Helper() out := installDepthCaller(t, caller) cmd := &cobra.Command{Use: "list"} err := runDriveListDepth(cmd, route, map[string]any{}, root, maxDepth, pattern, true, 0, driveListFilter{}) return decodeDepthResult(t, out), err } func TestCrossPlatformCoverageRunDriveListDepthDryRun(t *testing.T) { caller := &scriptedToolCaller{format: "json", dry: true} out := installDepthCaller(t, caller) cmd := &cobra.Command{Use: "list"} if err := runDriveListDepth(cmd, newDrivePanDepthRoute(), map[string]any{}, "", 2, "", true, 0, driveListFilter{}); err != nil { t.Fatal(err) } if caller.calls != 0 { t.Fatalf("dry-run calls = %d", caller.calls) } var payload map[string]any if err := json.Unmarshal(out.Bytes(), &payload); err != nil { t.Fatalf("dry-run output: %v", err) } if payload["dry_run"] != true { t.Fatalf("payload = %#v", payload) } } func TestCrossPlatformCoverageRunDriveListDepthPanBFS(t *testing.T) { useDriveDepthArgs(t) caller := &scriptedToolCaller{steps: []scriptedToolStep{ {text: `{"items":[{"fileId":"fA","name":"dirA","type":"FOLDER"},{"fileId":"fX","name":"x.txt","type":"FILE"}]}`}, {text: `{"items":[{"fileId":"fY","name":"y.txt","type":"FILE"}]}`}, }} out := installDepthCaller(t, caller) cmd := &cobra.Command{Use: "list"} if err := runDriveListDepth(cmd, newDrivePanDepthRoute(), map[string]any{}, "", 3, "", false, 0, driveListFilter{}); err != nil { t.Fatal(err) } if caller.calls != 2 { t.Fatalf("calls = %d, want 2", caller.calls) } items := decodeDepthResult(t, out)["items"].([]any) if len(items) != 3 { t.Fatalf("items = %#v", items) } var dirA, nested map[string]any for _, raw := range items { item := raw.(map[string]any) switch item["rel_path"] { case "dirA": dirA = item case "dirA/y.txt": nested = item } } if dirA == nil || nested == nil { t.Fatalf("rel_path tree = %#v", items) } if dirA["depth"] != float64(1) || dirA["parentId"] != "" { t.Fatalf("root item = %#v", dirA) } if nested["depth"] != float64(2) || nested["parentId"] != "fA" { t.Fatalf("nested item = %#v", nested) } } func TestCrossPlatformCoverageRunDriveListDepthMaxDepthSkipsEnqueue(t *testing.T) { useDriveDepthArgs(t) caller := &scriptedToolCaller{steps: []scriptedToolStep{ {text: `{"items":[{"fileId":"fA","name":"dirA","type":"FOLDER"}]}`}, }} result, err := runDepthBFS(t, caller, newDrivePanDepthRoute(), "", 1, "") if err != nil { t.Fatal(err) } if caller.calls != 1 { t.Fatalf("calls = %d, want 1", caller.calls) } if len(result["items"].([]any)) != 1 { t.Fatalf("items = %#v", result["items"]) } } func TestCrossPlatformCoverageRunDriveListDepthDedup(t *testing.T) { useDriveDepthArgs(t) caller := &scriptedToolCaller{steps: []scriptedToolStep{ {text: `{"items":[ {"fileId":"fA","name":"dirA","type":"FOLDER"}, {"fileId":"fA","name":"dirA-copy","type":"FOLDER"}, {"fileId":"","name":"no-id","type":"FOLDER"}, {"fileId":"fB","name":"dirB","type":"FOLDER"}]}`}, {text: `{"items":[{"fileId":"f1","name":"a.txt","type":"FILE"}]}`}, {text: `{"items":[{"fileId":"f2","name":"b.txt","type":"FILE"}]}`}, }} result, err := runDepthBFS(t, caller, newDrivePanDepthRoute(), "", 3, "") if err != nil { t.Fatal(err) } if caller.calls != 3 { t.Fatalf("calls = %d, want 3 (dedup + empty id skipped)", caller.calls) } if len(result["items"].([]any)) != 6 { t.Fatalf("items = %#v", result["items"]) } } func TestCrossPlatformCoverageRunDriveListDepthDocRouteAnomaly(t *testing.T) { caller := &scriptedToolCaller{steps: []scriptedToolStep{ {text: `{"nodes":[{"nodeId":"nB","name":"folderB","nodeType":"folder"},{"nodeId":"nD","name":"doc1","nodeType":"doc"}],"hasMore":false,"nextPageToken":"ignored"}`}, {text: `{"nodes":[{"nodeId":"nE","name":"inner","nodeType":"doc"}],"hasMore":true}`}, }} result, err := runDepthBFS(t, caller, newDocDepthRoute(), "root1", 3, "") if err != nil { t.Fatal(err) } if caller.calls != 2 { t.Fatalf("calls = %d, want 2 (hasMore=false stops authoritative route)", caller.calls) } errs := result["errors"].([]any) if len(errs) != 1 { t.Fatalf("errors = %#v", result["errors"]) } entry := errs[0].(map[string]any) if entry["folderId"] != "nB" || entry["reason"] != "api_error" { t.Fatalf("anomaly entry = %#v", entry) } if !strings.Contains(entry["message"].(string), "hasMore=true but nextToken is empty") { t.Fatalf("anomaly message = %#v", entry) } if len(result["items"].([]any)) != 3 { t.Fatalf("items = %#v", result["items"]) } } func TestCrossPlatformCoverageRunDriveListDepthRateLimitRetry(t *testing.T) { useDriveDepthArgs(t) caller := &scriptedToolCaller{steps: []scriptedToolStep{ {text: `{"items":[{"fileId":"fA","name":"dirA","type":"FOLDER"}]}`}, {text: `{"errorCode":"invalidRequest.rateLimited","errorMsg":"slow down"}`}, {text: `{"items":[{"fileId":"f1","name":"a.txt","type":"FILE"}]}`}, }} result, err := runDepthBFS(t, caller, newDrivePanDepthRoute(), "", 3, "") if err != nil { t.Fatal(err) } if caller.calls != 3 { t.Fatalf("calls = %d, want 3", caller.calls) } if errs := result["errors"].([]any); len(errs) != 0 { t.Fatalf("errors = %#v", errs) } if len(result["items"].([]any)) != 2 { t.Fatalf("items = %#v", result["items"]) } } func TestCrossPlatformCoverageRunDriveListDepthRateLimitResumesFromFailedPage(t *testing.T) { useDriveDepthArgs(t) caller := &depthArgsRecordingCaller{steps: []scriptedToolStep{ {text: `{"items":[{"fileId":"f1","name":"page1.txt","type":"FILE"}],"nextToken":"p2"}`}, {text: `{"errorCode":"invalidRequest.rateLimited","errorMsg":"slow down"}`}, {text: `{"items":[{"fileId":"f2","name":"page2.txt","type":"FILE"}]}`}, }} previousDeps := deps t.Cleanup(func() { deps = previousDeps }) InitDeps(caller) out := &bytes.Buffer{} deps.Out.w = out deps.Out.errW = io.Discard cmd := &cobra.Command{Use: "list"} if err := runDriveListDepth(cmd, newDrivePanDepthRoute(), map[string]any{}, "", 3, "", true, 0, driveListFilter{}); err != nil { t.Fatal(err) } if len(caller.calls) != 3 { t.Fatalf("calls = %d, want 3", len(caller.calls)) } if tok, _ := caller.calls[2]["nextToken"].(string); tok != "p2" { t.Fatalf("retry call args = %#v, want resume with nextToken=p2", caller.calls[2]) } items := decodeDepthResult(t, out)["items"].([]any) if len(items) != 2 { t.Fatalf("items = %#v, want 2 without duplicates", items) } } func TestCrossPlatformCoverageRunDriveListDepthRateLimitExhausted(t *testing.T) { useDriveDepthArgs(t) caller := &scriptedToolCaller{steps: []scriptedToolStep{ {text: `{"items":[{"fileId":"fA","name":"dirA","type":"FOLDER"}]}`}, {text: `{"errorCode":"invalidRequest.rateLimited","errorMsg":"slow down"}`}, }} result, err := runDepthBFS(t, caller, newDrivePanDepthRoute(), "", 3, "") if err != nil { t.Fatal(err) } if caller.calls != 3 { t.Fatalf("calls = %d, want 3 (one retry)", caller.calls) } errs := result["errors"].([]any) if len(errs) != 1 { t.Fatalf("errors = %#v", errs) } entry := errs[0].(map[string]any) if entry["reason"] != "rate_limited" || entry["folderId"] != "fA" { t.Fatalf("rate limit entry = %#v", entry) } } func TestCrossPlatformCoverageRunDriveListDepthRootFailure(t *testing.T) { useDriveDepthArgs(t) caller := &scriptedToolCaller{steps: []scriptedToolStep{ {text: `{"errorCode":"invalidRequest.rateLimited","errorMsg":"slow down"}`}, }} installDepthCaller(t, caller) cmd := &cobra.Command{Use: "list"} err := runDriveListDepth(cmd, newDrivePanDepthRoute(), map[string]any{}, "", 3, "", true, 0, driveListFilter{}) if err == nil { t.Fatal("root failure returned nil") } if caller.calls != 2 { t.Fatalf("calls = %d, want 2 (single retry then fail)", caller.calls) } } func TestCrossPlatformCoverageRunDriveListDepthUnrecoverable(t *testing.T) { useDriveDepthArgs(t) caller := &scriptedToolCaller{steps: []scriptedToolStep{ {text: `{"items":[{"fileId":"fA","name":"dirA","type":"FOLDER"},{"fileId":"fX","name":"x.txt","type":"FILE"}]}`}, {text: `{"errorCode":"DWS_SERVICE_UNAUTHORIZED"}`}, }} out := installDepthCaller(t, caller) cmd := &cobra.Command{Use: "list"} err := runDriveListDepth(cmd, newDrivePanDepthRoute(), map[string]any{}, "", 3, "", true, 0, driveListFilter{}) if err == nil { t.Fatal("unrecoverable returned nil") } var cliErr *CLIError if !errors.As(err, &cliErr) || cliErr.Code != CodeAuthTokenExpired { t.Fatalf("err = %T %v", err, err) } result := decodeDepthResult(t, out) if len(result["items"].([]any)) != 2 { t.Fatalf("partial items = %#v", result["items"]) } if len(result["errors"].([]any)) != 1 { t.Fatalf("errors = %#v", result["errors"]) } } func TestCrossPlatformCoverageRunDriveListDepthUnrecoverableEmitFailure(t *testing.T) { useDriveDepthArgs(t) caller := &scriptedToolCaller{steps: []scriptedToolStep{ {text: `{"errorCode":"DWS_SERVICE_UNAUTHORIZED"}`}, }} installDepthCaller(t, caller) deps.Out.w = failingWriter{} cmd := &cobra.Command{Use: "list"} err := runDriveListDepth(cmd, newDrivePanDepthRoute(), map[string]any{}, "", 3, "", true, 0, driveListFilter{}) if err == nil || !strings.Contains(err.Error(), "write failed") { t.Fatalf("err = %v, want emit failure", err) } } func TestCrossPlatformCoverageRunDriveListDepthPaginationLoop(t *testing.T) { useDriveDepthArgs(t) caller := &scriptedToolCaller{steps: []scriptedToolStep{ {text: `{"items":[],"nextToken":"t","hasMore":true}`}, }} installDepthCaller(t, caller) cmd := &cobra.Command{Use: "list"} err := runDriveListDepth(cmd, newDrivePanDepthRoute(), map[string]any{}, "", 3, "", true, 0, driveListFilter{}) if err == nil || !strings.Contains(err.Error(), "cursor loop suspected") { t.Fatalf("err = %v, want pagination anomaly", err) } maxPages := driveDepthMaxItems/driveDepthPageSize + 1 if caller.calls != maxPages { t.Fatalf("calls = %d, want %d", caller.calls, maxPages) } } func TestCrossPlatformCoverageRunDriveListDepthTruncation(t *testing.T) { useDriveDepthArgs(t) var sb strings.Builder sb.WriteString(`{"items":[`) for i := 0; i < driveDepthMaxItems; i++ { if i > 0 { sb.WriteString(",") } fmt.Fprintf(&sb, `{"fileId":"f%d","name":"file-%d.txt","type":"FILE"}`, i, i) } sb.WriteString(`]}`) caller := &scriptedToolCaller{steps: []scriptedToolStep{{text: sb.String()}}} result, err := runDepthBFS(t, caller, newDrivePanDepthRoute(), "", 3, "") if err != nil { t.Fatal(err) } if result["truncated"] != true { t.Fatalf("truncated = %#v", result["truncated"]) } if len(result["items"].([]any)) != driveDepthMaxItems { t.Fatalf("items len = %d", len(result["items"].([]any))) } } func TestCrossPlatformCoverageRunDriveListDepthCancelled(t *testing.T) { useDriveDepthArgs(t) caller := &scriptedToolCaller{} out := installDepthCaller(t, caller) ctx, cancel := context.WithCancel(context.Background()) cancel() cmd := &cobra.Command{Use: "list"} cmd.SetContext(ctx) err := runDriveListDepth(cmd, newDrivePanDepthRoute(), map[string]any{}, "", 3, "", true, 0, driveListFilter{}) var cancelErr *driveDepthCancelledError if !errors.As(err, &cancelErr) { t.Fatalf("err = %T %v, want driveDepthCancelledError", err, err) } result := decodeDepthResult(t, out) if result["truncated"] != true { t.Fatalf("cancelled result = %#v", result) } } func TestCrossPlatformCoverageRunDriveListDepthCancelledEmitFailure(t *testing.T) { useDriveDepthArgs(t) caller := &scriptedToolCaller{} installDepthCaller(t, caller) deps.Out.w = failingWriter{} ctx, cancel := context.WithCancel(context.Background()) cancel() cmd := &cobra.Command{Use: "list"} cmd.SetContext(ctx) err := runDriveListDepth(cmd, newDrivePanDepthRoute(), map[string]any{}, "", 3, "", true, 0, driveListFilter{}) if err == nil || !strings.Contains(err.Error(), "write failed") { t.Fatalf("err = %v, want emit failure", err) } } func TestCrossPlatformCoverageRunDriveListDepthFinalEmitFailure(t *testing.T) { useDriveDepthArgs(t) caller := &scriptedToolCaller{steps: []scriptedToolStep{ {text: `{"items":[{"fileId":"fX","name":"x.txt","type":"FILE"}]}`}, }} installDepthCaller(t, caller) deps.Out.w = failingWriter{} cmd := &cobra.Command{Use: "list"} err := runDriveListDepth(cmd, newDrivePanDepthRoute(), map[string]any{}, "", 3, "", true, 0, driveListFilter{}) if err == nil || !strings.Contains(err.Error(), "write failed") { t.Fatalf("err = %v, want emit failure", err) } } func TestCrossPlatformCoverageRunDriveListDepthPatternFilter(t *testing.T) { useDriveDepthArgs(t) caller := &scriptedToolCaller{steps: []scriptedToolStep{ {text: `{"items":[{"fileId":"fA","name":"dirA","type":"FOLDER"},{"fileId":"fX","name":"x.txt","type":"FILE"}]}`}, {text: `{"items":[{"fileId":"fY","name":"keep.xlsx","type":"FILE"}]}`}, }} result, err := runDepthBFS(t, caller, newDrivePanDepthRoute(), "", 3, "*.xlsx") if err != nil { t.Fatal(err) } items := result["items"].([]any) if len(items) != 1 || items[0].(map[string]any)["name"] != "keep.xlsx" { t.Fatalf("filtered = %#v", items) } } type cancelOnCallCaller struct { scriptedToolCaller cancel context.CancelFunc } func (c *cancelOnCallCaller) CallTool(ctx context.Context, productID, toolName string, args map[string]any) (*edition.ToolResult, error) { c.cancel() return c.scriptedToolCaller.CallTool(ctx, productID, toolName, args) } func TestCrossPlatformCoverageRunDriveListDepthCancelledInsidePagination(t *testing.T) { useDriveDepthArgs(t) ctx, cancel := context.WithCancel(context.Background()) t.Cleanup(cancel) route := newDrivePanDepthRoute() baseParse := route.parsePage route.parsePage = func(text string) ([]map[string]any, string, bool) { cancel() return baseParse(text) } caller := &scriptedToolCaller{steps: []scriptedToolStep{ {text: `{"items":[{"fileId":"fX","name":"x.txt","type":"FILE"}],"nextToken":"more"}`}, }} out := installDepthCaller(t, caller) cmd := &cobra.Command{Use: "list"} cmd.SetContext(ctx) err := runDriveListDepth(cmd, route, map[string]any{}, "", 3, "", true, 0, driveListFilter{}) var cancelErr *driveDepthCancelledError if !errors.As(err, &cancelErr) { t.Fatalf("err = %T %v, want driveDepthCancelledError", err, err) } result := decodeDepthResult(t, out) if len(result["items"].([]any)) != 1 || result["truncated"] != true { t.Fatalf("cancelled partial = %#v", result) } } func TestCrossPlatformCoverageRunDriveListDepthCancelledAfterFetch(t *testing.T) { useDriveDepthArgs(t) ctx, cancel := context.WithCancel(context.Background()) t.Cleanup(cancel) caller := &cancelOnCallCaller{ scriptedToolCaller: scriptedToolCaller{steps: []scriptedToolStep{ {text: `{"items":[{"fileId":"fX","name":"x.txt","type":"FILE"}]}`}, }}, cancel: cancel, } previousDeps := deps t.Cleanup(func() { deps = previousDeps }) InitDeps(caller) out := &bytes.Buffer{} deps.Out.w = out deps.Out.errW = io.Discard cmd := &cobra.Command{Use: "list"} cmd.SetContext(ctx) err := runDriveListDepth(cmd, newDrivePanDepthRoute(), map[string]any{}, "", 3, "", true, 0, driveListFilter{}) var cancelErr *driveDepthCancelledError if !errors.As(err, &cancelErr) { t.Fatalf("err = %T %v, want driveDepthCancelledError", err, err) } result := decodeDepthResult(t, out) if result["truncated"] != true { t.Fatalf("cancelled result = %#v", result) } }