// Copyright 2026 Alibaba Group // Licensed under the Apache License, Version 2.0 (the "License"); package main import ( "bytes" "os" "path/filepath" "strings" "testing" "github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/app" "github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/cli" "github.com/spf13/cobra" ) func TestCrossPlatformCoverageRunRepositoryAndSetupFailures(t *testing.T) { root, err := filepath.Abs("../../..") if err != nil { t.Fatal(err) } var stdout, stderr bytes.Buffer if code := run(root, app.NewRootCommand(), &stdout, &stderr); code != 0 { t.Fatalf("repository policy run = %d, stdout=%s stderr=%s", code, stdout.String(), stderr.String()) } if !strings.Contains(stdout.String(), "multi IM Skill chain check: ok") { t.Fatalf("success output = %q", stdout.String()) } stdout.Reset() stderr.Reset() if code := run(t.TempDir(), &cobra.Command{Use: "dws"}, &stdout, &stderr); code != 2 || !strings.Contains(stderr.String(), "read IM intent route manifest") { t.Fatalf("missing-manifest run = %d, stderr=%s", code, stderr.String()) } stdout.Reset() stderr.Reset() if code := run(root, &cobra.Command{Use: "dws"}, &stdout, &stderr); code != 1 || !strings.Contains(stderr.String(), "absent from BoundCommandRegistry") { t.Fatalf("unbound-root run = %d, stderr=%s", code, stderr.String()) } oldBuild, oldBind := buildEffective, bindEffective t.Cleanup(func() { buildEffective, bindEffective = oldBuild, oldBind }) buildEffective = func(*cobra.Command) (cli.EffectiveCommandRegistry, error) { return cli.EffectiveCommandRegistry{}, os.ErrInvalid } stdout.Reset() stderr.Reset() if code := run(root, app.NewRootCommand(), &stdout, &stderr); code != 2 || !strings.Contains(stderr.String(), "build effective CommandRegistry") { t.Fatalf("registry-build-failure run = %d, stderr=%s", code, stderr.String()) } buildEffective = oldBuild bindEffective = func(*cobra.Command, cli.EffectiveCommandRegistry) (cli.BoundCommandRegistry, error) { return cli.BoundCommandRegistry{}, os.ErrInvalid } stdout.Reset() stderr.Reset() if code := run(root, app.NewRootCommand(), &stdout, &stderr); code != 2 || !strings.Contains(stderr.String(), "bind effective CommandRegistry") { t.Fatalf("binding-failure run = %d, stderr=%s", code, stderr.String()) } bindEffective = oldBind failureRoot := t.TempDir() writeTestFile(t, failureRoot, manifestRelativePath, `{"version":1}`) stdout.Reset() stderr.Reset() if code := run(failureRoot, app.NewRootCommand(), &stdout, &stderr); code != 1 || !strings.Contains(stderr.String(), "multi IM Skill chain check failed") { t.Fatalf("validation-failure run = %d, stderr=%s", code, stderr.String()) } } func TestCrossPlatformCoverageMainUsesInjectableProcessBoundaries(t *testing.T) { oldGetwd, oldExit := mainGetwd, mainExit t.Cleanup(func() { mainGetwd, mainExit = oldGetwd, oldExit }) var exitCode int mainExit = func(code int) { exitCode = code } mainGetwd = func() (string, error) { return "", os.ErrPermission } main() if exitCode != 2 { t.Fatalf("getwd failure exit = %d", exitCode) } root, err := filepath.Abs("../../..") if err != nil { t.Fatal(err) } mainGetwd = func() (string, error) { return root, nil } main() if exitCode != 0 { t.Fatalf("successful main exit = %d", exitCode) } } func TestCrossPlatformCoverageValidateManifestAcceptsExactReviewedRoute(t *testing.T) { root := t.TempDir() writeTestFile(t, root, "skills/multi/dingtalk-chat/SKILL.md", "| 发消息 | `dws chat +send` | \n") writeTypedContractReference(t, root, "skills/multi/dingtalk-chat/references/contracts.md") writeEventHandoffReference(t, root, "skills/multi/dingtalk-event/references/event-im-output.md") manifest := routeManifest{ Version: 3, MarkerRoots: []string{"skills/multi/dingtalk-chat"}, RetiredScripts: []string{"skills/multi/dingtalk-chat/scripts/retired.py"}, ContractReference: "skills/multi/dingtalk-chat/references/contracts.md", HandoffReference: "skills/multi/dingtalk-event/references/event-im-output.md", Intents: []intentRoute{{ ID: "chat.send", PreferredTool: "chat.shortcut_send", ForbiddenDefaultTools: []string{"chat.atomic_send"}, References: []string{"skills/multi/dingtalk-chat/SKILL.md"}, }}, } tools := map[string]toolFact{ "chat.shortcut_send": {Canonical: "chat.shortcut_send", PrimaryPath: "chat +send", Confirmation: "user_required", UseWhen: []string{"普通发送"}, AvoidWhen: []string{"底层字段另选"}, HasMeta: true}, "chat.atomic_send": {Canonical: "chat.atomic_send", PrimaryPath: "chat message send", Confirmation: "not_required", UseWhen: []string{"底层字段"}, AvoidWhen: []string{"普通发送使用 +send"}, HasMeta: true}, } if failures := validateManifest(root, manifest, tools); len(failures) != 0 { t.Fatalf("failures = %v", failures) } } func TestCrossPlatformCoverageValidateManifestRejectsWrongMarkerAndSafetyDowngrade(t *testing.T) { root := t.TempDir() writeTestFile(t, root, "skills/multi/dingtalk-chat/SKILL.md", "| 发消息 | `dws chat message send` | \n") writeTypedContractReference(t, root, "skills/multi/dingtalk-chat/references/contracts.md") writeEventHandoffReference(t, root, "skills/multi/dingtalk-event/references/event-im-output.md") manifest := routeManifest{ Version: 3, MarkerRoots: []string{"skills/multi/dingtalk-chat"}, RetiredScripts: []string{"skills/multi/dingtalk-chat/scripts/retired.py"}, ContractReference: "skills/multi/dingtalk-chat/references/contracts.md", HandoffReference: "skills/multi/dingtalk-event/references/event-im-output.md", Intents: []intentRoute{{ ID: "chat.send", PreferredTool: "chat.shortcut_send", AllowedFallbacks: []routeFallback{{Tool: "chat.atomic_send", ReasonCode: "raw_field"}}, ForbiddenDefaultTools: []string{"chat.atomic_send"}, References: []string{"skills/multi/dingtalk-chat/SKILL.md"}, }}, } tools := map[string]toolFact{ "chat.shortcut_send": {Canonical: "chat.shortcut_send", PrimaryPath: "chat +send", Confirmation: "user_required", UseWhen: []string{"普通发送"}, AvoidWhen: []string{"底层字段另选"}, HasMeta: true}, "chat.atomic_send": {Canonical: "chat.atomic_send", PrimaryPath: "chat message send", Confirmation: "not_required", UseWhen: []string{"普通发送"}, HasMeta: true}, } failures := strings.Join(validateManifest(root, manifest, tools), "\n") for _, want := range []string{"confirmation", "needs non-empty use_when and avoid_when", "must contain preferred path", "uses forbidden default"} { if !strings.Contains(failures, want) { t.Fatalf("failures = %s, want %q", failures, want) } } } func TestCrossPlatformCoverageLoadManifestRejectsUnknownFields(t *testing.T) { path := filepath.Join(t.TempDir(), "manifest.json") if err := os.WriteFile(path, []byte(`{"version":1,"unknown":true}`), 0o600); err != nil { t.Fatal(err) } if _, err := loadManifest(path); err == nil || !strings.Contains(err.Error(), "unknown field") { t.Fatalf("error = %v", err) } } func TestCrossPlatformCoverageValidateRetiredScriptsRejectsRepublishedAndDuplicatePaths(t *testing.T) { root := t.TempDir() writeTestFile(t, root, "skills/multi/dingtalk-chat/scripts/export.py", "republished\n") failures := strings.Join(validateRetiredScripts(root, []string{ "skills/multi/dingtalk-chat/scripts/export.py", "skills/multi/dingtalk-chat/scripts/export.py", "../unsafe.py", }), "\n") for _, want := range []string{"was republished", "duplicate retired", "invalid retired"} { if !strings.Contains(failures, want) { t.Fatalf("failures = %s, want %q", failures, want) } } } func TestCrossPlatformCoverageValidateTypedContractReferenceRejectsDrift(t *testing.T) { root := t.TempDir() writeTypedContractReference(t, root, "contracts.md") path := filepath.Join(root, "contracts.md") data, err := os.ReadFile(path) if err != nil { t.Fatal(err) } data = []byte(strings.Replace(string(data), "`im.message-list.v1`", "`drifted`", 1)) if err := os.WriteFile(path, data, 0o600); err != nil { t.Fatal(err) } failures := strings.Join(validateTypedContractReference(root, "contracts.md"), "\n") if !strings.Contains(failures, "MESSAGE_RESULT contract differs") { t.Fatalf("failures = %s", failures) } } func TestCrossPlatformCoverageValidateEventHandoffReferenceRejectsNaturalTargetDrift(t *testing.T) { root := t.TempDir() writeEventHandoffReference(t, root, "handoff.md") path := filepath.Join(root, "handoff.md") data, err := os.ReadFile(path) if err != nil { t.Fatal(err) } data = []byte(strings.Replace(string(data), "--group ", "--chat-query ", 1)) if err := os.WriteFile(path, data, 0o600); err != nil { t.Fatal(err) } failures := strings.Join(validateEventHandoffReference(root, "handoff.md"), "\n") if !strings.Contains(failures, "exact stable-ID mapping") { t.Fatalf("failures = %s", failures) } } func TestCrossPlatformCoverageValidateReferencesAcceptCRLF(t *testing.T) { root := t.TempDir() for _, tc := range []struct { path string write func(*testing.T, string, string) validate func(string, string) []string }{ {path: "contracts.md", write: writeTypedContractReference, validate: validateTypedContractReference}, {path: "handoff.md", write: writeEventHandoffReference, validate: validateEventHandoffReference}, } { tc.write(t, root, tc.path) path := filepath.Join(root, tc.path) data, err := os.ReadFile(path) if err != nil { t.Fatal(err) } data = bytes.ReplaceAll(data, []byte("\n"), []byte("\r\n")) if err := os.WriteFile(path, data, 0o600); err != nil { t.Fatal(err) } if failures := tc.validate(root, tc.path); len(failures) != 0 { t.Errorf("%s CRLF failures = %v", tc.path, failures) } } } func TestCrossPlatformCoverageManifestFailureMatrix(t *testing.T) { root := t.TempDir() writeTypedContractReference(t, root, "contracts.md") writeEventHandoffReference(t, root, "handoff.md") writeTestFile(t, root, "refs/declared.md", " missing preferred; dws chat forbidden\n duplicate\n") writeTestFile(t, root, "refs/markers.md", "\n\n\n") tools := map[string]toolFact{ "preferred.empty": {PrimaryPath: "chat preferred", HasMeta: false}, "fallback.empty": {PrimaryPath: "chat fallback", HasMeta: false}, "fallback.different": {PrimaryPath: "chat fallback-different", HasMeta: true, Confirmation: "not_required"}, "forbidden.no-route": {PrimaryPath: "chat forbidden", HasMeta: true, Confirmation: "not_required", AvoidWhen: []string{"keep using lower tool"}}, "forbidden.no-entry": {PrimaryPath: "chat forbidden-missing"}, } manifest := routeManifest{ Version: 1, MarkerRoots: []string{"refs", "../unsafe", "missing-root"}, RetiredScripts: nil, ContractReference: "contracts.md", HandoffReference: "handoff.md", Intents: []intentRoute{ {ID: "INVALID ID"}, {ID: "preferred-absent", PreferredTool: "absent"}, {ID: "preferred-no-selection", PreferredTool: "forbidden.no-entry"}, { ID: "declared", PreferredTool: "preferred.empty", AllowedFallbacks: []routeFallback{ {}, {Tool: "fallback.empty", ReasonCode: "BAD-CODE"}, {Tool: "fallback.empty", ReasonCode: "duplicate"}, {Tool: "fallback.absent", ReasonCode: "missing"}, {Tool: "fallback.different", ReasonCode: "raw_field"}, }, ForbiddenDefaultTools: []string{"", "forbidden.absent", "forbidden.no-entry", "forbidden.no-route", "forbidden.no-route"}, References: []string{"../unsafe.md", "refs/wrong.txt", "refs/missing.md", "refs/declared.md", "refs/declared.md"}, }, {ID: "declared"}, }, } failures := strings.Join(validateManifest(root, manifest, tools), "\n") for _, want := range []string{ "manifest version", "retired_scripts", "intent id", "preferred tool", "ResolveMeta", "needs non-empty", "allowed fallback", "reason_code", "fallback tool", "confirmation", "forbidden default", "invalid reference", "does not exist", "repeats reference", "unknown dws-intent", "undeclared dws-intent", "missing its dws-intent marker", "has 2 dws-intent markers", "invalid marker root", "scan marker root", "duplicate intent id", } { if !strings.Contains(failures, want) { t.Errorf("failure matrix missing %q:\n%s", want, failures) } } if failures := validateManifest(root, routeManifest{}, nil); len(failures) == 0 { t.Fatal("empty manifest unexpectedly passed") } } func TestCrossPlatformCoverageReferenceFailureBranches(t *testing.T) { root := t.TempDir() if got := validateTypedContractReference(root, "../unsafe.md"); len(got) == 0 || !strings.Contains(got[0], "invalid contract_reference") { t.Fatalf("unsafe contract result = %#v", got) } if got := validateTypedContractReference(root, "missing.md"); len(got) == 0 || !strings.Contains(got[0], "read typed contract") { t.Fatalf("missing contract result = %#v", got) } writeTestFile(t, root, "malformed.md", "\n") if got := strings.Join(validateTypedContractReference(root, "malformed.md"), "\n"); !strings.Contains(got, "malformed MESSAGE_RESULT") || !strings.Contains(got, "marker pair") { t.Fatalf("malformed contract result = %s", got) } if got := validateEventHandoffReference(root, "../unsafe.md"); len(got) == 0 || !strings.Contains(got[0], "invalid handoff_reference") { t.Fatalf("unsafe handoff result = %#v", got) } if got := validateEventHandoffReference(root, "missing-handoff.md"); len(got) == 0 || !strings.Contains(got[0], "read event handoff") { t.Fatalf("missing handoff result = %#v", got) } writeTestFile(t, root, "handoff-markers.md", "no markers") if got := strings.Join(validateEventHandoffReference(root, "handoff-markers.md"), "\n"); !strings.Contains(got, "marker pair") { t.Fatalf("handoff marker result = %s", got) } if markdownCodeList(nil) != "—" || markdownBreakList(nil) != "—" { t.Fatal("empty markdown list rendering drifted") } tooLong := strings.Repeat("x", 5000) + ".py" if got := strings.Join(validateRetiredScripts(root, []string{tooLong}), "\n"); !strings.Contains(got, "inspect retired script") { t.Fatalf("long retired script result = %s", got) } for _, path := range []string{"", ".", "..", "../x", "a/../b"} { if safeRepositoryPath(path) { t.Errorf("unsafe repository path accepted: %q", path) } } if containsCLIPath("run dws chat send-more", "chat send") || !containsCLIPath("run dws chat send`", "chat send") { t.Fatal("CLI path boundary check drifted") } if stringSliceContains([]string{"a/b"}, "missing") { t.Fatal("string slice containment false positive") } } func TestCrossPlatformCoverageMarkerOpenFailure(t *testing.T) { root := t.TempDir() writeTestFile(t, root, "refs/marker.md", " dws chat preferred\n") oldOpen := markerOpen markerOpen = func(string) (*os.File, error) { return nil, os.ErrPermission } t.Cleanup(func() { markerOpen = oldOpen }) failures, _ := scanMarkers(root, []string{"refs"}, map[string]intentRoute{ "declared": {ID: "declared", PreferredTool: "preferred", References: []string{"refs/marker.md"}}, }, map[string]toolFact{"preferred": {PrimaryPath: "chat preferred"}}) if len(failures) == 0 || !strings.Contains(failures[0], "scan marker root") { t.Fatalf("marker open failures = %#v", failures) } } func writeTypedContractReference(t *testing.T, root, relative string) { t.Helper() var content strings.Builder for _, block := range []struct { name string body string }{ {name: "MESSAGE_RESULT", body: renderMessageResultContract()}, {name: "IDENTITY_CAPABILITY", body: renderIdentityCapabilityContract()}, {name: "CARD_WORKFLOW", body: renderCardWorkflowContract()}, {name: "CAPABILITY_BOUNDARY", body: renderCapabilityBoundaryContract()}, } { content.WriteString("\n") content.WriteString(block.body) content.WriteString("\n\n") } writeTestFile(t, root, relative, content.String()) } func writeEventHandoffReference(t *testing.T, root, relative string) { t.Helper() writeTestFile(t, root, relative, ` | event field | exact chat target | |---|---| | `+"`conversation_id`"+` | `+"`dws chat +messages-send --as user --group `"+` | | `+"`sender_open_dingtalk_id`"+` | `+"`dws chat +messages-send --as user --open-dingtalk-id `"+` | `) } func writeTestFile(t *testing.T, root, relative, content string) { t.Helper() path := filepath.Join(root, filepath.FromSlash(relative)) if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil { t.Fatal(err) } if err := os.WriteFile(path, []byte(content), 0o600); err != nil { t.Fatal(err) } }