package app import ( "context" "errors" "io" "strings" "testing" authpkg "github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/auth" apperrors "github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/errors" "github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/executor" "github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/safety" "github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/transport" "github.com/DingTalk-Real-AI/dingtalk-workspace-cli/pkg/edition" ) type runnerCoverageFallback struct { result executor.Result err error } func (f runnerCoverageFallback) Run(context.Context, executor.Invocation) (executor.Result, error) { return f.result, f.err } func TestCrossPlatformCoverageRunnerRemainingRoutingCoverage(t *testing.T) { oldResolveMulti := runnerResolveMultiProfileSelections oldResolveProfile := runnerResolveProfile oldCachedToken := runnerGetCachedRuntimeToken t.Cleanup(func() { runnerResolveMultiProfileSelections = oldResolveMulti runnerResolveProfile = oldResolveProfile runnerGetCachedRuntimeToken = oldCachedToken }) created := newCommandRunnerWithFlags(&GlobalFlags{Timeout: 2}) if created.(*runtimeRunner).transport == nil { t.Fatal("runner transport was not created") } wantErr := errors.New("profiles failed") runnerResolveMultiProfileSelections = func(string, string) ([]multiProfileSelection, bool, error) { return nil, false, wantErr } if _, err := (&runtimeRunner{}).Run(context.Background(), executor.Invocation{}); err == nil { t.Fatal("profile resolution error was accepted") } inv := executor.Invocation{CanonicalProduct: "product", Tool: "tool"} prefetched := make(chan struct{}, 1) runnerGetCachedRuntimeToken = func(context.Context) (string, error) { prefetched <- struct{}{} return "", nil } r := &runtimeRunner{ transport: transport.NewClient(nil), fallback: runnerCoverageFallback{}, } directMiss := inv directMiss.Kind = "helper_invocation" if _, err := r.runSingle(context.Background(), directMiss, false); err == nil || !strings.Contains(err.Error(), "no dynamic endpoint registered for product or tool") { t.Fatalf("direct runtime miss = %v", err) } directHit := executor.Invocation{Kind: "helper_invocation", CanonicalProduct: defaultPATProductID, Tool: "pat", DryRun: true} if got, err := r.runSingle(context.Background(), directHit, false); err != nil || got.Response["dry_run"] != true { t.Fatalf("direct runtime hit = %#v, %v", got, err) } if _, err := r.runSingle(context.Background(), inv, true); err == nil { t.Fatal("endpoint miss succeeded") } <-prefetched runnerResolveProfile = func(_ string, selector string) (*authpkg.Profile, error) { if selector == "a,b" { return nil, errors.New("not a combined profile") } if selector == "a" { return nil, wantErr } return nil, nil } if _, _, err := resolveMultiProfileSelections("", "a,b"); !errors.Is(err, wantErr) { t.Fatalf("profile error = %v", err) } runnerResolveProfile = func(_ string, selector string) (*authpkg.Profile, error) { if selector == "a,b" { return nil, errors.New("not a combined profile") } if selector == "a" { return &authpkg.Profile{CorpID: "corp-a"}, nil } return nil, nil } if _, _, err := resolveMultiProfileSelections("", "a,b"); err == nil || !strings.Contains(err.Error(), "not found") { t.Fatalf("nil profile error = %v", err) } selections := []multiProfileSelection{ {Selector: "bad", Profile: authpkg.Profile{CorpID: "bad"}}, {Selector: "good", Profile: authpkg.Profile{CorpID: "good"}}, } r = &runtimeRunner{fallback: runnerCoverageFallback{err: wantErr}} result, err := r.runMultiProfile(context.Background(), inv, selections[:1]) if err != nil || result.Response == nil { t.Fatalf("multi failure aggregation = %#v, %v", result, err) } r.fallback = runnerCoverageFallback{result: executor.Result{Response: map[string]any{"endpoint": "local", "value": 1}}} result, err = r.runMultiProfile(context.Background(), inv, selections[1:]) if err != nil || result.Response == nil { t.Fatalf("multi success aggregation = %#v, %v", result, err) } r = &runtimeRunner{ transport: transport.NewClient(nil), globalFlags: &GlobalFlags{DryRun: true}, fallback: runnerCoverageFallback{}, } overrideInv := inv overrideInv.Kind = "helper_invocation" overrideInv.DryRun = true t.Setenv("DINGTALK_PRODUCT_MCP_URL", "https://override.test") got, err := r.runSingle(context.Background(), overrideInv, false) if err != nil || got.Response["endpoint"] != "https://override.test" { t.Fatalf("direct runtime override = %#v, %v", got, err) } } func TestCrossPlatformCoverageRunnerRemainingExecutionCoverage(t *testing.T) { t.Setenv("DWS_CONFIG_DIR", t.TempDir()) oldEdition := edition.Get() oldPreflight := runnerPreflightDocDownload oldCall := runnerCallTool oldHandle := runnerHandlePatAuthCheck oldRetry := runnerRetryWithPatAuthRetry oldCapture := runnerCaptureRuntimeFailure oldResolveSnapshot := runnerResolveAuthSnapshot t.Cleanup(func() { edition.Override(oldEdition) runnerPreflightDocDownload = oldPreflight runnerCallTool = oldCall runnerHandlePatAuthCheck = oldHandle runnerRetryWithPatAuthRetry = oldRetry runnerCaptureRuntimeFailure = oldCapture runnerResolveAuthSnapshot = oldResolveSnapshot }) pluginAuthMu.Lock() oldPluginRegistry := pluginAuthRegistry pluginAuthRegistry = make(map[string]*PluginAuth) pluginAuthMu.Unlock() t.Cleanup(func() { pluginAuthMu.Lock() pluginAuthRegistry = oldPluginRegistry pluginAuthMu.Unlock() }) runnerCaptureRuntimeFailure = func(executor.Invocation, error, error) {} runnerPreflightDocDownload = func(*runtimeRunner, context.Context, *transport.Client, string, executor.Invocation) error { return nil } runnerCallTool = func(*transport.Client, context.Context, string, string, map[string]any) (transport.ToolCallResult, error) { return transport.ToolCallResult{Content: map[string]any{"value": 1}}, nil } r := &runtimeRunner{ transport: transport.NewClient(nil), globalFlags: &GlobalFlags{Token: "token", Timeout: 1}, } inv := executor.Invocation{CanonicalProduct: "product", Tool: "tool", Params: map[string]any{"x": 1}} if got, err := r.executeInvocation(context.Background(), "https://example.test", inv); err != nil || !got.Invocation.Implemented { t.Fatalf("default auth execution = %#v, %v", got, err) } runnerResolveAuthSnapshot = func(*runtimeRunner, context.Context) (AccessTokenSnapshot, error) { return AccessTokenSnapshot{ AccessToken: "international-token", LoginRegion: authpkg.LoginRegionInternational, LoginRegionKnown: true, }, nil } successfulCall := runnerCallTool routedEndpoint := "" runnerCallTool = func(_ *transport.Client, _ context.Context, endpoint, _ string, _ map[string]any) (transport.ToolCallResult, error) { routedEndpoint = endpoint return transport.ToolCallResult{Content: map[string]any{"value": 1}}, nil } if _, err := r.executeInvocation(context.Background(), "https://mcp-gw.dingtalk.com/server/contact", inv); err != nil { t.Fatalf("international auth execution = %v", err) } if routedEndpoint != "https://mcp-gw.dingtalk.io/server/contact" { t.Fatalf("international routed endpoint = %q", routedEndpoint) } runnerResolveAuthSnapshot = oldResolveSnapshot runnerCallTool = successfulCall wantErr := errors.New("preflight") runnerPreflightDocDownload = func(*runtimeRunner, context.Context, *transport.Client, string, executor.Invocation) error { return wantErr } if _, err := r.executeInvocation(context.Background(), "https://example.test", inv); !errors.Is(err, wantErr) { t.Fatalf("preflight error = %v", err) } patErr := &apperrors.PATError{RawJSON: `{"code":"PAT_NO_PERMISSION"}`} runnerPreflightDocDownload = func(*runtimeRunner, context.Context, *transport.Client, string, executor.Invocation) error { return patErr } retrying := context.WithValue(context.Background(), patRetryingKey, true) if _, err := r.executeInvocation(retrying, "https://example.test", inv); !errors.Is(err, patErr) { t.Fatalf("retrying preflight PAT = %v", err) } handled := errors.New("handled PAT") runnerHandlePatAuthCheck = func(context.Context, *runtimeRunner, executor.Invocation, *apperrors.PATError, string, io.Writer) (executor.Result, error) { return executor.Result{}, handled } if _, err := r.executeInvocation(context.Background(), "https://example.test", inv); !errors.Is(err, handled) { t.Fatalf("handled preflight PAT = %v", err) } runnerPreflightDocDownload = oldPreflight runnerPreflightDocDownload = func(*runtimeRunner, context.Context, *transport.Client, string, executor.Invocation) error { return nil } authErr := apperrors.NewAuth("expired", apperrors.WithReason("http_401")) runnerCallTool = func(*transport.Client, context.Context, string, string, map[string]any) (transport.ToolCallResult, error) { return transport.ToolCallResult{}, authErr } overrideErr := errors.New("auth override") edition.Override(&edition.Hooks{OnAuthError: func(string, error) error { return overrideErr }}) if _, err := r.executeInvocation(context.Background(), "https://example.test", inv); !errors.Is(err, overrideErr) { t.Fatalf("auth override = %v", err) } edition.Override(&edition.Hooks{OnAuthError: func(string, error) error { return nil }}) if _, err := r.executeInvocation(context.Background(), "https://example.test", inv); !errors.Is(err, authErr) { t.Fatalf("auth passthrough = %v", err) } scopeErr := errors.New("missing_scope calendar:read") runnerCallTool = func(*transport.Client, context.Context, string, string, map[string]any) (transport.ToolCallResult, error) { return transport.ToolCallResult{}, scopeErr } retried := errors.New("scope retried") runnerRetryWithPatAuthRetry = func(context.Context, executor.Runner, executor.Invocation, *PatScopeError, string, io.Writer) (executor.Result, error) { return executor.Result{}, retried } if _, err := r.executeInvocation(context.Background(), "https://example.test", inv); !errors.Is(err, retried) { t.Fatalf("scope retry = %v", err) } runnerCallTool = func(*transport.Client, context.Context, string, string, map[string]any) (transport.ToolCallResult, error) { return transport.ToolCallResult{}, wantErr } edition.Override(&edition.Hooks{}) if _, err := r.executeInvocation(context.Background(), "https://example.test", inv); !errors.Is(err, wantErr) { t.Fatalf("generic call error = %v", err) } patContent := map[string]any{"code": "PAT_NO_PERMISSION", "data": map[string]any{"flowId": "f"}} runnerCallTool = func(*transport.Client, context.Context, string, string, map[string]any) (transport.ToolCallResult, error) { return transport.ToolCallResult{Content: patContent}, nil } edition.Override(&edition.Hooks{ClassifyToolResult: func(map[string]any) error { return patErr }}) if _, err := r.executeInvocation(retrying, "https://example.test", inv); !errors.Is(err, patErr) { t.Fatalf("edition retry PAT = %v", err) } if _, err := r.executeInvocation(context.Background(), "https://example.test", inv); !errors.Is(err, handled) { t.Fatalf("edition handled PAT = %v", err) } edition.Override(&edition.Hooks{ClassifyToolResult: func(map[string]any) error { return wantErr }}) if _, err := r.executeInvocation(context.Background(), "https://example.test", inv); !errors.Is(err, wantErr) { t.Fatalf("edition classification = %v", err) } edition.Override(&edition.Hooks{}) if _, err := r.executeInvocation(retrying, "https://example.test", inv); err == nil { t.Fatal("built-in retrying PAT succeeded") } if _, err := r.executeInvocation(context.Background(), "https://example.test", inv); !errors.Is(err, handled) { t.Fatalf("built-in handled PAT = %v", err) } callCount := 0 edition.Override(&edition.Hooks{ClassifyToolResult: func(map[string]any) error { callCount++ if callCount%2 == 0 { return wantErr } return nil }}) runnerCallTool = func(*transport.Client, context.Context, string, string, map[string]any) (transport.ToolCallResult, error) { return transport.ToolCallResult{IsError: true, Content: map[string]any{"message": "business"}}, nil } if _, err := r.executeInvocation(context.Background(), "https://example.test", inv); !errors.Is(err, wantErr) { t.Fatalf("business hook = %v", err) } edition.Override(&edition.Hooks{}) runnerCallTool = func(*transport.Client, context.Context, string, string, map[string]any) (transport.ToolCallResult, error) { return transport.ToolCallResult{IsError: true, Blocks: []transport.ContentBlock{{Text: "missing_scope mail:read"}}, Content: map[string]any{}}, nil } if _, err := r.executeInvocation(context.Background(), "https://example.test", inv); !errors.Is(err, retried) { t.Fatalf("business scope retry = %v", err) } r.scanner = coverageScanner{report: safety.Report{Scanned: true, Findings: []safety.Finding{{Pattern: "bad"}}}} r.enforceContentScan = true runnerCallTool = func(*transport.Client, context.Context, string, string, map[string]any) (transport.ToolCallResult, error) { return transport.ToolCallResult{Content: map[string]any{"value": 1}}, nil } if _, err := r.executeInvocation(context.Background(), "https://example.test", inv); err == nil { t.Fatal("scan failure succeeded") } } func TestCrossPlatformCoverageRunnerRemainingStdioAuthAndHeadersCoverage(t *testing.T) { oldStdioInit := runnerStdioEnsureInitialized oldStdioList := runnerStdioListTools oldStdioCall := runnerStdioCallTool oldEdition := edition.Get() t.Cleanup(func() { runnerStdioEnsureInitialized = oldStdioInit runnerStdioListTools = oldStdioList runnerStdioCallTool = oldStdioCall edition.Override(oldEdition) StopAllStdioClients() }) client := transport.NewStdioClient("unused", nil, nil) RegisterStdioClient("stdio-product", client) r := &runtimeRunner{globalFlags: &GlobalFlags{Timeout: 1}} inv := executor.Invocation{CanonicalProduct: "stdio-product", Tool: "tool"} wantErr := errors.New("stdio failed") runnerStdioEnsureInitialized = func(*transport.StdioClient, context.Context) error { return wantErr } if _, err := r.executeStdioInvocationAtEndpoint(context.Background(), "", inv); err == nil || !strings.Contains(err.Error(), "stdio initialize failed") { t.Fatalf("stdio initialize error = %v", err) } runnerStdioEnsureInitialized = func(*transport.StdioClient, context.Context) error { return nil } runnerStdioListTools = func(*transport.StdioClient, context.Context) (transport.ToolsListResult, error) { return transport.ToolsListResult{ Tools: []transport.ToolDescriptor{{ Name: "tool", InputSchema: map[string]any{"type": "object"}, }}, }, nil } runnerStdioCallTool = func(*transport.StdioClient, context.Context, string, map[string]any) (transport.ToolCallResult, error) { return transport.ToolCallResult{}, wantErr } if _, err := r.executeStdioInvocationAtEndpoint(context.Background(), "", inv); err == nil || !strings.Contains(err.Error(), "stdio failed") { t.Fatalf("stdio call error = %v", err) } runnerStdioCallTool = func(*transport.StdioClient, context.Context, string, map[string]any) (transport.ToolCallResult, error) { return transport.ToolCallResult{IsError: true, Content: map[string]any{"message": "tool failed"}}, nil } if _, err := r.executeStdioInvocationAtEndpoint(context.Background(), "", inv); err == nil || !strings.Contains(err.Error(), "tool failed") { t.Fatalf("stdio tool error = %v", err) } runnerStdioCallTool = func(*transport.StdioClient, context.Context, string, map[string]any) (transport.ToolCallResult, error) { return transport.ToolCallResult{Content: map[string]any{"ok": true}}, nil } if got, err := r.executeStdioInvocationAtEndpoint(context.Background(), "", inv); err != nil || !got.Invocation.Implemented { t.Fatalf("stdio success = %#v, %v", got, err) } RegisterStdioClient("plugin/server-key", client) overlayIDInvocation := inv overlayIDInvocation.CanonicalProduct = "overlay-id" if got, err := r.executeInvocation( context.Background(), "stdio://plugin/server-key", overlayIDInvocation, ); err != nil || !got.Invocation.Implemented { t.Fatalf("stdio endpoint-key lookup = %#v, %v", got, err) } r.globalFlags.Token = " explicit " if got, err := r.resolveAuthToken(context.Background()); err != nil || got != "explicit" { t.Fatalf("explicit auth token = %q, %v", got, err) } edition.Override(&edition.Hooks{TokenProvider: func(_ context.Context, fallback func() (string, error)) (string, error) { _, _ = fallback() return "provided", nil }}) r.globalFlags.Token = "" if got, err := r.resolveAuthToken(context.Background()); err != nil || got != "provided" { t.Fatalf("provided auth token = %q, %v", got, err) } if got, err := resolveRuntimeAuthToken(context.Background(), " runtime "); err != nil || got != "runtime" { t.Fatalf("runtime explicit token = %q, %v", got, err) } edition.Override(&edition.Hooks{TokenProvider: func(context.Context, func() (string, error)) (string, error) { return "", errors.New("snapshot failed") }}) if _, err := r.resolveAuthToken(context.Background()); err == nil || !strings.Contains(err.Error(), "snapshot failed") { t.Fatalf("resolveAuthToken error = %v", err) } t.Setenv(envDWSChannel, "channel") edition.Override(&edition.Hooks{ MergeHeaders: func(headers map[string]string) map[string]string { return headers }, EnterpriseCredentialHeaders: func(headers map[string]string) map[string]string { headers["x-enterprise"] = "yes" return headers }, }) headers := resolveIdentityHeaders() if headers["x-dws-channel"] != "channel" || headers["x-enterprise"] != "yes" { t.Fatalf("identity headers = %#v", headers) } if got := detectBusinessError(map[string]any{"content": map[string]any{"success": false, "errorMsg": "nested"}}); got != "nested" { t.Fatalf("nested business error = %q", got) } if got := detectBusinessError(map[string]any{"success": false, "data": map[string]any{"success": false, "errorMsg": "nested-first"}}); got != "nested-first" { t.Fatalf("nested-first business error = %q", got) } }