Files
dingtalk-workspace-cli/internal/helpers/mail_template_update_test.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)
}
}