Files
dingtalk-workspace-cli/internal/pat/coverage_edges_test.go
玉澜andCursor e4fde3917d test(schema): close overall coverage non-regression gap
Cover remaining cli/agentmetadata/pat edge paths so aggregate coverage
stays at or above the merge-base overall percentage.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-02 22:06:56 +08:00

628 lines
26 KiB
Go

// Copyright 2026 Alibaba Group
// Licensed under the Apache License, Version 2.0 (the "License");
package pat
import (
"bytes"
"context"
"errors"
"io"
"os"
"path/filepath"
"strings"
"testing"
"github.com/spf13/cobra"
apperrors "github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/errors"
"github.com/DingTalk-Real-AI/dingtalk-workspace-cli/pkg/edition"
)
func TestOverallCoverageGapBatchGrantConfirmation(t *testing.T) {
cmd := &cobra.Command{Use: "chmod"}
cmd.Flags().Bool("yes", false, "")
if err := requireBatchGrantConfirmation(cmd, true, []string{"a", "b"}); err == nil {
t.Fatal("batch grant without --yes must fail")
}
_ = cmd.Flags().Set("yes", "true")
if err := requireBatchGrantConfirmation(cmd, true, []string{"a", "b"}); err != nil {
t.Fatalf("--yes should allow batch grant: %v", err)
}
if err := requireBatchGrantConfirmation(cmd, false, []string{"only"}); err != nil {
t.Fatalf("single-scope non-plan grant should pass: %v", err)
}
}
type patEdgeCaller struct {
results []*edition.ToolResult
errs []error
calls int
dryRun bool
}
func (c *patEdgeCaller) CallTool(context.Context, string, string, map[string]any) (*edition.ToolResult, error) {
index := c.calls
c.calls++
var result *edition.ToolResult
var err error
if index < len(c.results) {
result = c.results[index]
}
if index < len(c.errs) {
err = c.errs[index]
}
return result, err
}
func (*patEdgeCaller) Format() string { return "json" }
func (c *patEdgeCaller) DryRun() bool { return c.dryRun }
func (*patEdgeCaller) Fields() string { return "" }
func (*patEdgeCaller) JQ() string { return "" }
type patFailWriter struct{}
func (patFailWriter) Write([]byte) (int, error) { return 0, errors.New("write failed") }
func patText(text string) *edition.ToolResult {
return &edition.ToolResult{Content: []edition.ContentBlock{{Type: "text", Text: text}}}
}
func TestCrossPlatformCoverageBrowserPolicyInjectedEdges(t *testing.T) {
originalRead := patPolicyReadFile
originalHome := patPolicyUserHomeDir
originalMarshal := patPolicyMarshal
originalWrite := patPolicyAtomicWrite
originalEdition := edition.Get()
t.Cleanup(func() {
patPolicyReadFile = originalRead
patPolicyUserHomeDir = originalHome
patPolicyMarshal = originalMarshal
patPolicyAtomicWrite = originalWrite
edition.Override(originalEdition)
})
failure := errors.New("injected failure")
t.Setenv("DWS_CONFIG_DIR", "/env/config")
if got := patConfigDir(); got != "/env/config" {
t.Fatalf("env config dir = %q", got)
}
t.Setenv("DWS_CONFIG_DIR", "")
edition.Override(&edition.Hooks{ConfigDir: func() string { return "/edition/config" }})
if got := patConfigDir(); got != "/edition/config" {
t.Fatalf("edition config dir = %q", got)
}
edition.Override(&edition.Hooks{})
patPolicyUserHomeDir = func() (string, error) { return "", failure }
if got := patConfigDir(); got != ".dws" {
t.Fatalf("failed home config dir = %q", got)
}
homeDir := filepath.Join(t.TempDir(), "home")
patPolicyUserHomeDir = func() (string, error) { return homeDir, nil }
if got := patConfigDir(); got != filepath.Join(homeDir, ".dws") {
t.Fatalf("home config dir = %q", got)
}
patPolicyReadFile = func(string) ([]byte, error) { return nil, failure }
if _, err := LoadBrowserPolicy("x"); !errors.Is(err, failure) {
t.Fatalf("read error = %v", err)
}
patPolicyReadFile = func(string) ([]byte, error) { return []byte(`{`), nil }
if _, err := LoadBrowserPolicy("x"); err == nil {
t.Fatal("invalid policy decoded")
}
patPolicyReadFile = func(string) ([]byte, error) { return []byte(`{}`), nil }
if policy, err := LoadBrowserPolicy("x"); err != nil || policy.Agents == nil {
t.Fatalf("empty policy = %#v, %v", policy, err)
}
patPolicyReadFile = originalRead
patPolicyMarshal = func(any, string, string) ([]byte, error) { return nil, failure }
if err := saveBrowserPolicy("x", nil); !errors.Is(err, failure) {
t.Fatalf("marshal error = %v", err)
}
patPolicyMarshal = originalMarshal
patPolicyAtomicWrite = func(string, []byte) error { return failure }
if err := saveBrowserPolicy("x", &BrowserPolicy{}); !errors.Is(err, failure) {
t.Fatalf("write error = %v", err)
}
patPolicyAtomicWrite = originalWrite
policyDir := t.TempDir()
patPolicyReadFile = func(string) ([]byte, error) { return nil, failure }
if _, err := ResolveBrowserPolicy(policyDir, ""); !errors.Is(err, failure) {
t.Fatalf("resolve policy read error = %v", err)
}
if EffectiveOpenBrowser(policyDir) != true {
t.Fatal("policy error should preserve browser-open fallback")
}
if _, err := SetBrowserPolicy(policyDir, "", true); !errors.Is(err, failure) {
t.Fatalf("set policy read error = %v", err)
}
patPolicyReadFile = originalRead
if _, err := ResolveBrowserPolicy(t.TempDir(), "bad code"); err == nil {
t.Fatal("invalid agent code accepted")
}
if _, err := SetBrowserPolicy(t.TempDir(), "bad code", true); err == nil {
t.Fatal("invalid policy agent code accepted")
}
patPolicyAtomicWrite = func(string, []byte) error { return failure }
if _, err := SetBrowserPolicy(t.TempDir(), "agent", true); !errors.Is(err, failure) {
t.Fatalf("agent save error = %v", err)
}
if _, err := SetBrowserPolicy(t.TempDir(), "", true); !errors.Is(err, failure) {
t.Fatalf("default save error = %v", err)
}
}
func TestCrossPlatformCoverageBrowserPolicyCommandWriteError(t *testing.T) {
t.Setenv("DWS_CONFIG_DIR", t.TempDir())
cmd := newBrowserPolicyCommand()
cmd.SetOut(patFailWriter{})
cmd.SetArgs([]string{"--enabled=true"})
if err := cmd.Execute(); err == nil {
t.Fatal("output write error did not propagate")
}
if got := EffectiveOpenBrowser(os.Getenv("DWS_CONFIG_DIR")); !got {
t.Fatal("saved browser policy was not effective")
}
}
func TestCrossPlatformCoverageBrowserPolicyCommandSetError(t *testing.T) {
badDir := filepath.Join(t.TempDir(), "file")
if err := os.WriteFile(badDir, []byte("x"), 0o600); err != nil {
t.Fatal(err)
}
t.Setenv("DWS_CONFIG_DIR", badDir)
cmd := newBrowserPolicyCommand()
cmd.SetArgs([]string{"--enabled=true"})
if err := cmd.Execute(); err == nil {
t.Fatal("policy command ignored load error")
}
}
func TestCrossPlatformCoveragePATPureHelperEdges(t *testing.T) {
if got := collectChmodProductCodes([]string{"", "a,a", " b "}, []string{"b", "c"}); strings.Join(got, ",") != "a,b,c" {
t.Fatalf("product codes = %#v", got)
}
if _, err := callPATBatchGrantWithLegacyFallback(t.Context(), nil, "", "", nil, nil, nil); err == nil {
t.Fatal("nil batch grant caller accepted")
}
if _, err := callPATBatchPlan(t.Context(), nil, "", "", nil); err == nil {
t.Fatal("nil batch plan caller accepted")
}
if _, err := callPATToolWithLegacyFallback(t.Context(), nil, "", "", "", nil, nil); err == nil {
t.Fatal("nil legacy caller accepted")
}
caller := &patEdgeCaller{errs: []error{errors.New("boom")}}
if _, err := callPATToolWithLegacyFallback(t.Context(), caller, "pat", "tool", "", nil, nil); err == nil {
t.Fatal("empty alias error did not propagate")
}
caller = &patEdgeCaller{results: []*edition.ToolResult{patText(`{"code":"PAT_FORGED_IDENTITY_FIELD"}`)}, errs: []error{nil, errors.New("second failed")}}
if _, err := callPATBatchToolWithIdentityFallback(t.Context(), caller, "agent", "", "tool", map[string]any{"agentCode": "agent"}); err == nil {
t.Fatal("identity fallback retry error did not propagate")
}
if !strings.HasPrefix(newBatchClientRequestID(""), "batch-") {
t.Fatal("default request ID prefix missing")
}
if got := normalizeProductCodes([]string{"", "a,a", " b "}); strings.Join(got, ",") != "a,b" {
t.Fatalf("normalized product codes = %#v", got)
}
for scope, want := range map[string]string{"": "", "mail.read": "mail", "doc:read": "doc", "drive": "drive", " x.y:z ": "x"} {
if got := productCodeFromScope(scope); got != want {
t.Fatalf("productCodeFromScope(%q) = %q, want %q", scope, got, want)
}
}
if !isEmptyToolResult(nil) || !isEmptyToolResult(&edition.ToolResult{}) || !isEmptyToolResult(&edition.ToolResult{Content: []edition.ContentBlock{{Type: "image"}}}) {
t.Fatal("empty tool result detection failed")
}
if firstToolResultText(nil) != "" || firstToolResultText(&edition.ToolResult{Content: []edition.ContentBlock{{Type: "image", Text: "x"}}}) != "" {
t.Fatal("first text extraction failed")
}
if patResultAgentCode(nil) != "" || patResultAgentCode(patText(`{`)) != "" {
t.Fatal("invalid PAT result produced agent code")
}
for raw, want := range map[string]string{
`{"agentCode":"top"}`: "top",
`{"data":{"agentCode":"data"}}`: "data",
`{"result":{"agentCode":"result"}}`: "result",
`{"result":{"data":{"agentCode":"deep"}}}`: "deep",
`{}`: "",
} {
if got := patResultAgentCode(patText(raw)); got != want {
t.Fatalf("agent code from %s = %q, want %q", raw, got, want)
}
}
if err := ensurePATResultAgentCode(nil, ""); err != nil {
t.Fatal(err)
}
if err := ensurePATIdentityFallbackAgentCode(nil, ""); err != nil {
t.Fatal(err)
}
if err := ensurePATIdentityFallbackAgentCode(nil, "expected"); err == nil {
t.Fatal("missing fallback agent code accepted")
}
if patBatchResultHasCode(nil, func(string) bool { return true }) || patBatchResultHasCode(patText(`{`), func(string) bool { return true }) {
t.Fatal("invalid batch result matched")
}
if !patBatchResultHasCode(patText(`{"error_code":"match"}`), func(code string) bool { return code == "match" }) {
t.Fatal("error_code was not matched")
}
if isPATBatchFallbackError(nil) || !isPATBatchFallbackError(errors.New("PAT_BATCH_AUTH_UNSUPPORTED")) {
t.Fatal("batch fallback error detection failed")
}
if isToolNotRegisteredError(nil) || !isToolNotRegisteredError(errors.New("unknown tool")) {
t.Fatal("tool registration error detection failed")
}
if hasScopeKeyShapeMismatch(nil, nil) || hasScopeKeyShapeMismatch(map[string]any{}, map[string]any{}) {
t.Fatal("scope shape mismatch false positive")
}
canonical := map[string]any{"scopes": []string{"a"}}
legacy := map[string]any{"scope": "a"}
if isLegacyGrantSchemaMismatchError(nil, canonical, legacy) || isLegacyGrantSchemaMismatchError(&apperrors.PATError{RawJSON: "scope validation"}, canonical, legacy) {
t.Fatal("legacy mismatch accepted excluded error")
}
for _, message := range []string{"missing parameter", "scope missing_scope", "scope invalid permission denied", "scope unknown"} {
_ = isLegacyGrantSchemaMismatchError(errors.New(message), canonical, legacy)
}
if normalizedPATErrorText(nil) != "" {
t.Fatal("nil normalized error text was non-empty")
}
typed := apperrors.NewAPI("message", apperrors.WithReason("reason"), apperrors.WithHint("hint"))
if got := normalizedPATErrorText(typed); !strings.Contains(got, "reason") || !strings.Contains(got, "hint") {
t.Fatalf("normalized typed error = %q", got)
}
}
func TestCrossPlatformCoveragePATPlanExtractionEdges(t *testing.T) {
invalidResults := []*edition.ToolResult{nil, patText(`{`), patText(`{}`)}
for _, result := range invalidResults {
_, _ = extractLoginRecommendProducts(result)
_, _ = extractBatchPlanAllGranted(result)
_, _ = extractSelectedScopes(result)
_, _ = extractSelectedScopesAllowEmpty(result)
}
productsJSON := `{"data":{"selectedScopes":["mail.read",12,""],"items":[12,{"scope":""},{"scope":"mail.read","productName":"","displayName":"Read"},{"scope":"mail.write","operationSummary":"Write"},{"scope":"mail.other","operationSummary":"Write"},{"scope":"mail.more","operationSummary":"More"},{"scope":"mail.last","operationSummary":"Last"}]}}`
products, err := extractLoginRecommendProducts(patText(productsJSON))
if err != nil || len(products) != 1 || products[0].ProductCode != "mail" || products[0].SelectedScopeCount != 1 {
t.Fatalf("products = %#v, %v", products, err)
}
fallbackJSON := `{"data":{"selectedScopes":["doc.read","doc.write","",12],"items":[]}}`
products, err = extractLoginRecommendProducts(patText(fallbackJSON))
if err != nil || len(products) != 1 || products[0].ScopeCount != 2 {
t.Fatalf("fallback products = %#v, %v", products, err)
}
if _, err := extractSelectedScopes(patText(`{"data":{}}`)); err == nil {
t.Fatal("empty selected scopes accepted")
}
if got, err := extractSelectedScopes(patText(`{"data":{"allGranted":true}}`)); err != nil || len(got) != 0 {
t.Fatalf("all-granted scopes = %#v, %v", got, err)
}
if _, err := extractSelectedScopes(patText(`{"data":{"selectedScopes":[12," "]}}`)); err == nil {
t.Fatal("non-string scopes accepted")
}
if got, err := extractSelectedScopes(patText(`{"data":{"selectedScopes":[12," "],"allGranted":true}}`)); err != nil || len(got) != 0 {
t.Fatalf("filtered all-granted scopes = %#v, %v", got, err)
}
if got, err := extractSelectedScopesAllowEmpty(patText(`{"data":{"selectedScopes":[12," ","one"]}}`)); err != nil || len(got) != 1 {
t.Fatalf("allow-empty scopes = %#v, %v", got, err)
}
}
func TestCrossPlatformCoveragePATResultAndFlagEdges(t *testing.T) {
if err := handleToolResult(nil, nil, nil); err == nil {
t.Fatal("nil result accepted")
}
if err := handleToolResultForWriter(io.Discard, nil, nil); err == nil {
t.Fatal("nil writer result accepted")
}
if err := classifyToolResultText(nil); err == nil {
t.Fatal("nil result classified successfully")
}
nonText := &edition.ToolResult{Content: []edition.ContentBlock{{Type: "image", Text: "x"}}}
if err := handleToolResultForWriter(io.Discard, nonText, nil); err == nil {
t.Fatal("non-text result accepted")
}
if err := classifyToolResultText(nonText); err != nil {
t.Fatal(err)
}
patFailure := patText(`{"code":"PAT_NO_PERMISSION"}`)
if _, err := captureStdout(t, func() error { return handleToolResult(nil, nil, patFailure) }); err == nil {
t.Fatal("PAT error result was accepted by stdout handler")
}
if _, err := captureStdout(t, func() error { return handleToolResult(nil, nil, nonText) }); err == nil {
t.Fatal("non-text result was accepted by stdout handler")
}
if err := handleToolResultForWriter(io.Discard, patFailure, nil); err == nil {
t.Fatal("PAT error result accepted")
}
if err := classifyToolResultText(patFailure); err == nil {
t.Fatal("PAT error was not classified")
}
if err := handleToolResultForWriter(nil, patText(`{"data":{}}`), nil); err != nil {
t.Fatalf("nil output writer: %v", err)
}
var buf bytes.Buffer
if err := handleToolResultForWriter(&buf, patText(`plain text`), nil); err != nil || !strings.Contains(buf.String(), "plain text") {
t.Fatalf("plain writer result = %q, %v", buf.String(), err)
}
if commandBoolFlag(nil, "verbose") || commandFlagChanged(nil, "format") || commandStringFlag(nil, "format") != "" {
t.Fatal("nil command flag helpers returned values")
}
root := &cobra.Command{Use: "root"}
root.PersistentFlags().Bool("verbose", true, "")
root.PersistentFlags().String("format", "raw", "")
child := &cobra.Command{Use: "child"}
root.AddCommand(child)
if !commandBoolFlag(child, "verbose") || commandStringFlag(child, "format") != "raw" {
t.Fatal("persistent flags were not resolved")
}
if commandFlagChanged(child, "format") {
t.Fatal("unchanged format reported changed")
}
if err := root.PersistentFlags().Set("format", "json"); err != nil {
t.Fatal(err)
}
if !commandFlagChanged(child, "format") {
t.Fatal("changed persistent format not detected")
}
local := &cobra.Command{Use: "local"}
local.Flags().Bool("verbose", true, "")
local.Flags().String("format", "json", "")
if !commandBoolFlag(local, "verbose") || commandStringFlag(local, "format") != "json" {
t.Fatal("local flags were not resolved")
}
if err := local.Flags().Set("format", "raw"); err != nil {
t.Fatal(err)
}
if !commandFlagChanged(local, "format") {
t.Fatal("changed local format not detected")
}
}
func TestCrossPlatformCoveragePATAuthorizationSummaryEdges(t *testing.T) {
if formatPATAuthorizationSummary("not json", nil) != "" || formatPATAuthorizationSummary(`{}`, nil) != "" {
t.Fatal("invalid summary payload rendered")
}
dry := &patEdgeCaller{dryRun: true}
texts := []string{
`{"success":true,"data":{"agentCode":"a","grantType":"once","allGranted":true,"items":[],"selectedScopes":[],"grantedScopes":[],"alreadyGrantedScopes":[],"skippedScopes":[],"pendingScopes":[]}}`,
`{"code":"OK","data":{"selectedScopes":["a"]}}`,
`{"data":{"selectedScopes":["a"]}}`,
`{"data":{"pendingScopes":["a"]}}`,
`{"data":{"items":["a"],"selectedScopes":"wrong"}}`,
}
for i, text := range texts {
caller := edition.ToolCaller(nil)
if i == 1 {
caller = dry
}
if got := formatPATAuthorizationSummary(text, caller); got == "" {
t.Fatalf("summary %d was empty", i)
}
}
if _, ok := countField(map[string]any{"values": []string{"a"}}, "values"); !ok {
t.Fatal("[]string count was not recognized")
}
if _, ok := countField(map[string]any{}, "missing"); ok {
t.Fatal("missing count was recognized")
}
if _, ok := countField(map[string]any{"bad": 1}, "bad"); ok {
t.Fatal("invalid count was recognized")
}
}
func TestCrossPlatformCoverageLoginRecommendWrappers(t *testing.T) {
if err := RunLoginRecommendAuthorization(t.Context(), nil, io.Discard); err == nil {
t.Fatal("nil login recommend caller accepted")
}
if _, err := PlanLoginRecommendAuthorization(t.Context(), nil); err == nil {
t.Fatal("nil plan caller accepted")
}
allGranted := patText(`{"data":{"selectedScopes":[],"allGranted":true,"items":[]}}`)
caller := &patEdgeCaller{results: []*edition.ToolResult{allGranted}}
var buf bytes.Buffer
if err := RunLoginRecommendAuthorization(t.Context(), caller, &buf); err != nil || buf.Len() == 0 {
t.Fatalf("login recommend wrapper = %q, %v", buf.String(), err)
}
caller = &patEdgeCaller{results: []*edition.ToolResult{allGranted}}
plan, err := PlanLoginRecommendAuthorization(t.Context(), caller)
if err != nil || !plan.AllGranted {
t.Fatalf("login recommend plan = %#v, %v", plan, err)
}
}
func TestCrossPlatformCoverageChmodCommandRemainingBranches(t *testing.T) {
cmd := newChmodCommand(nil)
if err := cmd.Args(cmd, []string{"scope"}); err != nil {
t.Fatal(err)
}
if err := cmd.Args(cmd, nil); err == nil {
t.Fatal("empty chmod arguments accepted")
}
cmd = newChmodCommand(nil)
if err := cmd.Flags().Parse([]string{"--recommend"}); err != nil {
t.Fatal(err)
}
if err := cmd.Args(cmd, nil); err != nil {
t.Fatalf("recommend args: %v", err)
}
cmd = newChmodCommand(nil)
if err := cmd.Flags().Parse([]string{"--product", "mail"}); err != nil {
t.Fatal(err)
}
if err := cmd.Args(cmd, nil); err != nil {
t.Fatalf("product args: %v", err)
}
run := func(c edition.ToolCaller, args ...string) error {
command := newChmodCommand(c)
root := &cobra.Command{Use: "dws"}
root.PersistentFlags().Bool("yes", false, "")
root.PersistentFlags().Bool("dry-run", false, "")
root.AddCommand(command)
// Catalog user_required: pass --dry-run when the caller is dry-run,
// otherwise --yes so ConfirmSafety does not mask the branch under test.
if c != nil && c.DryRun() {
args = append([]string{"chmod", "--dry-run"}, args...)
} else {
args = append([]string{"chmod", "--yes"}, args...)
}
root.SetArgs(args)
root.SilenceErrors = true
root.SilenceUsage = true
return root.Execute()
}
dryError := &patEdgeCaller{dryRun: true, errs: []error{errors.New("plan failed")}}
if err := run(dryError, "--recommend"); err == nil {
t.Fatal("dry-run plan error did not propagate")
}
dryMismatch := &patEdgeCaller{dryRun: true, results: []*edition.ToolResult{patText(`{"data":{"agentCode":"other"}}`)}}
if err := run(dryMismatch, "--recommend", "--agentCode", "expected"); err == nil {
t.Fatal("dry-run plan agent mismatch accepted")
}
dryPreview := &patEdgeCaller{dryRun: true}
if err := run(dryPreview, "scope", "--grant-type", "session", "--session-id", "sid"); err != nil {
t.Fatalf("dry-run session preview: %v", err)
}
if err := run(nil, "scope"); err == nil {
t.Fatal("nil chmod runtime accepted")
}
planError := &patEdgeCaller{errs: []error{errors.New("plan failed")}}
if err := run(planError, "--recommend"); err == nil {
t.Fatal("plan error did not propagate")
}
planMismatch := &patEdgeCaller{results: []*edition.ToolResult{patText(`{"data":{"agentCode":"other"}}`)}}
if err := run(planMismatch, "--recommend", "--agentCode", "expected"); err == nil {
t.Fatal("plan agent mismatch accepted")
}
badScopes := &patEdgeCaller{results: []*edition.ToolResult{patText(`{"data":{}}`)}}
if err := run(badScopes, "--recommend"); err == nil {
t.Fatal("invalid selected scopes accepted")
}
}
func TestCrossPlatformCoverageLoginRecommendErrorMatrix(t *testing.T) {
caller := &patEdgeCaller{errs: []error{errors.New("plan failed")}}
if _, err := PlanLoginRecommendAuthorization(t.Context(), caller); err == nil {
t.Fatal("plan wrapper error did not propagate")
}
if _, _, _, err := planLoginRecommend(t.Context(), &patEdgeCaller{}, nil, false); err == nil {
t.Fatal("all-scope plan without products accepted")
}
if _, _, _, err := planLoginRecommend(t.Context(), &patEdgeCaller{errs: []error{errors.New("call failed")}}, nil, true); err == nil {
t.Fatal("plan call error did not propagate")
}
if _, _, _, err := planLoginRecommend(t.Context(), &patEdgeCaller{results: []*edition.ToolResult{patText(`{"code":"PAT_NO_PERMISSION"}`)}}, nil, true); err == nil {
t.Fatal("classified plan result accepted")
}
if _, _, _, err := planLoginRecommend(t.Context(), &patEdgeCaller{results: []*edition.ToolResult{patText(`{}`)}}, nil, true); err == nil {
t.Fatal("malformed plan result accepted")
}
validProductPlan := patText(`{"data":{"selectedScopes":["mail.read"],"items":[{"scope":"mail.read","productCode":"mail"}]}}`)
initial := &LoginRecommendPlan{Result: validProductPlan, Scopes: []string{"mail.read"}}
if err := RunLoginRecommendAuthorizationWithOptions(t.Context(), &patEdgeCaller{}, io.Discard, LoginRecommendOptions{
InitialPlan: initial,
ProductSelector: func([]LoginRecommendProduct) ([]string, error) {
return nil, errors.New("selection failed")
},
}); err == nil {
t.Fatal("selector error did not propagate")
}
if err := RunLoginRecommendAuthorizationWithOptions(t.Context(), &patEdgeCaller{}, io.Discard, LoginRecommendOptions{
InitialPlan: initial,
ProductSelector: func([]LoginRecommendProduct) ([]string, error) {
return nil, nil
},
}); err == nil {
t.Fatal("empty product selection accepted")
}
if err := RunLoginRecommendAuthorizationWithOptions(t.Context(), &patEdgeCaller{errs: []error{errors.New("replan failed")}}, io.Discard, LoginRecommendOptions{
InitialPlan: initial,
ProductSelector: func([]LoginRecommendProduct) ([]string, error) {
return []string{"mail"}, nil
},
}); err == nil {
t.Fatal("selector replan error did not propagate")
}
if err := RunLoginRecommendAuthorizationWithOptions(t.Context(), &patEdgeCaller{}, io.Discard, LoginRecommendOptions{
ScopeMode: LoginRecommendScopeAll,
InitialPlan: &LoginRecommendPlan{Result: patText(`{"data":{"selectedScopes":[],"items":[]}}`), Scopes: []string{"synthetic"}},
ProductSelector: func([]LoginRecommendProduct) ([]string, error) {
return nil, nil
},
}); err == nil {
t.Fatal("all-scope mode without products accepted")
}
allGranted := patText(`{"data":{"selectedScopes":[],"allGranted":true,"items":[]}}`)
var output bytes.Buffer
if err := RunLoginRecommendAuthorizationWithOptions(t.Context(), &patEdgeCaller{results: []*edition.ToolResult{allGranted}}, &output, LoginRecommendOptions{
InitialPlan: initial,
ProductSelector: func([]LoginRecommendProduct) ([]string, error) {
return []string{"mail"}, nil
},
}); err != nil || output.Len() == 0 {
t.Fatalf("all-granted replan = %q, %v", output.String(), err)
}
if err := RunLoginRecommendAuthorizationWithOptions(t.Context(), &patEdgeCaller{errs: []error{errors.New("grant failed")}}, io.Discard, LoginRecommendOptions{
InitialPlan: initial,
}); err == nil {
t.Fatal("grant error did not propagate")
}
if err := RunLoginRecommendAuthorizationWithOptions(t.Context(), &patEdgeCaller{}, io.Discard, LoginRecommendOptions{
InitialPlan: &LoginRecommendPlan{Result: patText(`{`), Scopes: []string{"scope"}},
ProductSelector: func([]LoginRecommendProduct) ([]string, error) {
return []string{"mail"}, nil
},
}); err == nil {
t.Fatal("invalid initial plan products accepted")
}
}
func TestCrossPlatformCoverageLegacySchemaMismatchWithoutValidationKeyword(t *testing.T) {
canonical := map[string]any{"scopes": []string{"a"}}
legacy := map[string]any{"scope": "a"}
if isLegacyGrantSchemaMismatchError(errors.New("scope problem"), canonical, legacy) {
t.Fatal("ambiguous scope error triggered legacy fallback")
}
}
func TestCrossPlatformCoverageChmodValidateRequiresTargetSelection(t *testing.T) {
// The declared Validate hook mirrors the cobra Args gate for callers that
// bypass Args (the contract RunE pipeline runs Validate first): with no
// positional scope, no product/domain expansion, and no --recommend, the
// command must fail closed before any tool call.
cmd := newChmodCommand(&patEdgeCaller{})
err := cmd.RunE(cmd, nil)
if err == nil || !strings.Contains(err.Error(), "accepts 1 arg(s), received 0") {
t.Fatalf("chmod validate without targets err = %v", err)
}
}
func TestCrossPlatformCoverageChmodValidateGrantTypeAndSessionRules(t *testing.T) {
// Pure string validation in the declared Validate hook: platform-neutral,
// fails closed before any tool call on both Windows and macOS.
cmd := newChmodCommand(&patEdgeCaller{})
if err := cmd.Flags().Set("grant-type", "forever"); err != nil {
t.Fatal(err)
}
err := cmd.RunE(cmd, []string{"mail.mail:read"})
if err == nil || !strings.Contains(err.Error(), `invalid --grant-type "forever"`) {
t.Fatalf("chmod invalid grant-type err = %v", err)
}
// session grants need an explicit --session-id when no session env is set.
t.Setenv("DINGTALK_SESSION_ID", "")
t.Setenv("DWS_SESSION_ID", "")
t.Setenv("REWIND_SESSION_ID", "")
cmd = newChmodCommand(&patEdgeCaller{})
if err := cmd.Flags().Set("grant-type", "session"); err != nil {
t.Fatal(err)
}
err = cmd.RunE(cmd, []string{"mail.mail:read"})
if err == nil || !strings.Contains(err.Error(), "--session-id is required when --grant-type is session") {
t.Fatalf("chmod session without session-id err = %v", err)
}
}