135 lines
4.6 KiB
Go
135 lines
4.6 KiB
Go
// Copyright 2026 Alibaba Group
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
package helpers
|
|
|
|
import (
|
|
"context"
|
|
"io"
|
|
"reflect"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/DingTalk-Real-AI/dingtalk-workspace-cli/pkg/edition"
|
|
)
|
|
|
|
type mailTemplateUpdateCaller struct {
|
|
dryRun bool
|
|
dryRunChecks int
|
|
calls int
|
|
arguments map[string]any
|
|
}
|
|
|
|
func (c *mailTemplateUpdateCaller) CallTool(_ context.Context, _, _ string, arguments map[string]any) (*edition.ToolResult, error) {
|
|
c.calls++
|
|
c.arguments = arguments
|
|
return &edition.ToolResult{Content: []edition.ContentBlock{{Type: "text", Text: `{}`}}}, nil
|
|
}
|
|
|
|
func (*mailTemplateUpdateCaller) Format() string { return "json" }
|
|
func (c *mailTemplateUpdateCaller) DryRun() bool {
|
|
c.dryRunChecks++
|
|
return c.dryRun
|
|
}
|
|
func (*mailTemplateUpdateCaller) Fields() string { return "" }
|
|
func (*mailTemplateUpdateCaller) JQ() string { return "" }
|
|
|
|
func executeMailTemplateUpdate(t *testing.T, caller *mailTemplateUpdateCaller, arguments ...string) error {
|
|
t.Helper()
|
|
previousDeps := deps
|
|
t.Cleanup(func() { deps = previousDeps })
|
|
InitDeps(caller)
|
|
deps.Out.w = io.Discard
|
|
deps.Out.errW = io.Discard
|
|
|
|
cmd := newMailCommand()
|
|
cmd.PersistentFlags().Bool("dry-run", false, "preview only")
|
|
cmd.SilenceErrors = true
|
|
cmd.SilenceUsage = true
|
|
cmd.SetArgs(arguments)
|
|
return cmd.Execute()
|
|
}
|
|
|
|
func TestMailTemplateUpdateRejectsNoOpBeforeToolCaller(t *testing.T) {
|
|
for _, test := range []struct {
|
|
name string
|
|
dryRun bool
|
|
args []string
|
|
}{
|
|
{
|
|
name: "real execution",
|
|
args: []string{"template", "update", "--email", "user@example.com", "--id", "template-1"},
|
|
},
|
|
{
|
|
name: "dry run",
|
|
dryRun: true,
|
|
args: []string{"--dry-run", "template", "update", "--email", "user@example.com", "--id", "template-1"},
|
|
},
|
|
{
|
|
name: "blank actual payload",
|
|
args: []string{"template", "update", "--email", "user@example.com", "--id", "template-1", "--subject", " ", "--to", " , "},
|
|
},
|
|
} {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
caller := &mailTemplateUpdateCaller{dryRun: test.dryRun}
|
|
err := executeMailTemplateUpdate(t, caller, test.args...)
|
|
if err == nil || !strings.Contains(err.Error(), "至少需要指定一个更新字段") {
|
|
t.Fatalf("mail template update error = %v", err)
|
|
}
|
|
if caller.calls != 0 || caller.dryRunChecks != 0 {
|
|
t.Fatalf("no-op reached ToolCaller: calls=%d dry_run_checks=%d", caller.calls, caller.dryRunChecks)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestMailTemplateUpdateAcceptsEveryRuntimeUpdateField(t *testing.T) {
|
|
for _, test := range []struct {
|
|
name string
|
|
flag string
|
|
value string
|
|
wantKey string
|
|
wantValue any
|
|
}{
|
|
{name: "from", flag: "--from", value: "sender@example.com", wantKey: "from", wantValue: "sender@example.com"},
|
|
{name: "subject", flag: "--subject", value: "updated subject", wantKey: "subject", wantValue: "updated subject"},
|
|
{name: "public content", flag: "--content", value: "updated body", wantKey: "body", wantValue: "updated body"},
|
|
{name: "hidden body alias", flag: "--body", value: "updated body", wantKey: "body", wantValue: "updated body"},
|
|
{name: "name", flag: "--name", value: "updated name", wantKey: "name", wantValue: "updated name"},
|
|
{name: "to", flag: "--to", value: "first@example.com, second@example.com", wantKey: "toRecipients", wantValue: []string{"first@example.com", "second@example.com"}},
|
|
{name: "cc", flag: "--cc", value: "copy@example.com", wantKey: "ccRecipients", wantValue: []string{"copy@example.com"}},
|
|
} {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
caller := &mailTemplateUpdateCaller{}
|
|
err := executeMailTemplateUpdate(t, caller,
|
|
"template", "update", "--email", "user@example.com", "--id", "template-1",
|
|
test.flag, test.value,
|
|
)
|
|
if err != nil {
|
|
t.Fatalf("mail template update error = %v", err)
|
|
}
|
|
if caller.calls != 1 {
|
|
t.Fatalf("ToolCaller calls = %d, want 1", caller.calls)
|
|
}
|
|
if got := caller.arguments[test.wantKey]; !reflect.DeepEqual(got, test.wantValue) {
|
|
t.Fatalf("RPC %s = %#v, want %#v", test.wantKey, got, test.wantValue)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestMailTemplateUpdateValidDryRunReachesPreviewOnly(t *testing.T) {
|
|
caller := &mailTemplateUpdateCaller{dryRun: true}
|
|
err := executeMailTemplateUpdate(t, caller,
|
|
"--dry-run", "template", "update", "--email", "user@example.com", "--id", "template-1",
|
|
"--subject", "updated subject",
|
|
)
|
|
if err != nil {
|
|
t.Fatalf("mail template update dry-run error = %v", err)
|
|
}
|
|
if caller.calls != 0 || caller.dryRunChecks == 0 {
|
|
t.Fatalf("dry-run execution: calls=%d dry_run_checks=%d", caller.calls, caller.dryRunChecks)
|
|
}
|
|
}
|