Files
dingtalk-workspace-cli/internal/helpers/contact_update_commands_test.go

212 lines
9.4 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 (
"io"
"os"
"reflect"
"strings"
"testing"
)
func runContactUpdateCommand(t *testing.T, input string, args ...string) (*contactEnterpriseCaller, error) {
t.Helper()
previousDeps := deps
previousArgs := os.Args
t.Cleanup(func() {
deps = previousDeps
os.Args = previousArgs
})
caller := &contactEnterpriseCaller{}
InitDeps(caller)
deps.Out.w = io.Discard
os.Args = append([]string{"dws", "contact"}, args...)
root := newContactCommand()
root.PersistentFlags().Bool("yes", false, "skip confirmation")
RegisterCamelCaseAliases(root)
root.SetIn(strings.NewReader(input))
root.SetOut(io.Discard)
root.SetErr(io.Discard)
root.SilenceErrors = true
root.SilenceUsage = true
root.SetArgs(args)
return caller, root.Execute()
}
func TestCrossPlatformCoverageContactUpdateCommandsExposeExpectedFlags(t *testing.T) {
root := newContactCommand()
cases := []struct {
path []string
flags []string
}{
{[]string{"dept", "create"}, []string{"name", "parent", "create-dept-group"}},
{[]string{"dept", "update"}, []string{"dept", "name", "parent"}},
{[]string{"user", "update"}, []string{"user-id", "org-user-name", "depts", "master-user-id"}},
{[]string{"user", "update-self"}, []string{"nick", "avatar-file-id"}},
{[]string{"user", "update-ownness"}, []string{"user-id", "ownness-text"}},
{[]string{"account", "update"}, []string{"user-id", "org-user-name", "depts", "master-user-id", "nick", "avatar-file-id"}},
}
for _, tc := range cases {
cmd := requireWukongSyncCommand(t, root, tc.path...)
requireWukongSyncFlags(t, cmd, tc.flags...)
}
}
func TestCrossPlatformCoverageContactUpdateCommandsMapMCPArguments(t *testing.T) {
tests := []struct {
name string
args []string
toolName string
wantArgs map[string]any
}{
{
name: "create department at root",
args: []string{"dept", "create", "--name", " 产品部 ", "--create-dept-group=true", "--yes"},
toolName: "department_create",
wantArgs: map[string]any{"deptName": "产品部", "createDeptGroup": true},
},
{
name: "create department with camel aliases",
args: []string{"dept", "create", "--deptName", "研发组", "--superDeptId", "42", "--createDeptGroup=false", "--yes"},
toolName: "department_create",
wantArgs: map[string]any{"deptName": "研发组", "createDeptGroup": false, "superDeptId": int64(42)},
},
{
name: "update department",
args: []string{"dept", "modify", "--dept-id", "7", "--name", "研发中心", "--parent", "1", "--yes"},
toolName: "department_update",
wantArgs: map[string]any{"deptId": int64(7), "deptName": "研发中心", "superDeptId": int64(1)},
},
{
name: "update employee",
args: []string{"user", "update", "--userId", "user-1", "--orgUserName", "张三", "--depts", `[{"deptId":1}]`, "--masterUserId", "manager-1", "--yes"},
toolName: "employee_update",
wantArgs: map[string]any{
"userId": "user-1",
"orgUserName": "张三",
"depts": []map[string]any{{"deptId": float64(1)}},
"masterUserId": "manager-1",
},
},
{
name: "update current user profile",
args: []string{"user", "update-me", "--nick", "新昵称", "--avatarFileId", "file-1", "--yes"},
toolName: "self_user_profile_update",
wantArgs: map[string]any{"nick": "新昵称", "avatarFileId": "file-1"},
},
{
name: "update user ownness",
args: []string{"user", "update-ownness", "--user-id", "user-1", "--ownness-text", "居家办公中", "--yes"},
toolName: "user_ownness_update",
wantArgs: map[string]any{"userId": "user-1", "ownnessText": "居家办公中"},
},
{
name: "update user ownness with aliases",
args: []string{"user", "set-ownness", "--userId", "user-1", "--ownnessText", "专注开发中", "--yes"},
toolName: "user_ownness_update",
wantArgs: map[string]any{"userId": "user-1", "ownnessText": "专注开发中"},
},
{
name: "update enterprise account",
args: []string{"account", "edit", "--user-id", "user-2", "--org-user-name", "李四", "--depts", `[{"deptId":2}]`, "--master-user-id", "manager-2", "--nick", "小李", "--avatar-file-id", "file-2", "--yes"},
toolName: "exclusive_account_user_update",
wantArgs: map[string]any{
"userId": "user-2",
"orgUserName": "李四",
"depts": []map[string]any{{"deptId": float64(2)}},
"masterUserId": "manager-2",
"nick": "小李",
"avatarFileId": "file-2",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
caller, err := runContactUpdateCommand(t, "", tt.args...)
if err != nil {
t.Fatalf("command returned error: %v", err)
}
if len(caller.calls) != 1 {
t.Fatalf("tool call count = %d, want 1", len(caller.calls))
}
call := caller.calls[0]
if call.productID != "contact" || call.toolName != tt.toolName {
t.Fatalf("tool call = %s/%s, want contact/%s", call.productID, call.toolName, tt.toolName)
}
if !reflect.DeepEqual(call.args, tt.wantArgs) {
t.Fatalf("tool args = %#v, want %#v", call.args, tt.wantArgs)
}
})
}
}
func TestCrossPlatformCoverageContactUpdateCommandsRequireConfirmation(t *testing.T) {
tests := [][]string{
{"dept", "create", "--name", "产品部", "--create-dept-group=true"},
{"dept", "update", "--dept", "7", "--name", "研发中心"},
{"user", "update", "--user-id", "user-1", "--org-user-name", "张三"},
{"user", "update-self", "--nick", "新昵称"},
{"user", "update-ownness", "--user-id", "user-1", "--ownness-text", "居家办公中"},
{"account", "update", "--user-id", "user-2", "--nick", "小李"},
}
for _, args := range tests {
t.Run(strings.Join(args[:2], "-"), func(t *testing.T) {
caller, err := runContactUpdateCommand(t, "no\n", args...)
if err == nil || !strings.Contains(err.Error(), "用户取消了操作") {
t.Fatalf("declined confirmation error = %v, want 用户取消了操作", err)
}
if len(caller.calls) != 0 {
t.Fatalf("declined confirmation made %d remote call(s)", len(caller.calls))
}
})
}
}
func TestCrossPlatformCoverageContactUpdateCommandsValidateInput(t *testing.T) {
tests := []struct {
name string
args []string
wantErr string
}{
{"create missing name", []string{"dept", "create", "--create-dept-group=true", "--yes"}, "required"},
{"create blank name", []string{"dept", "create", "--name", " ", "--create-dept-group=true", "--yes"}, "不能为空"},
{"create missing group choice", []string{"dept", "create", "--name", "产品部", "--yes"}, "--create-dept-group"},
{"create detached false is rejected", []string{"dept", "create", "--name", "产品部", "--create-dept-group", "false", "--yes"}, "unknown command"},
{"create invalid parent", []string{"dept", "create", "--name", "产品部", "--create-dept-group=true", "--parent", "bad", "--yes"}, "must be an integer"},
{"update invalid department", []string{"dept", "update", "--dept", "root", "--name", "产品部", "--yes"}, "根部门 deptId=1"},
{"update invalid parent", []string{"dept", "update", "--dept", "7", "--name", "产品部", "--parent", "bad", "--yes"}, "must be an integer"},
{"update missing name", []string{"dept", "update", "--dept", "7", "--yes"}, "required"},
{"update blank name", []string{"dept", "update", "--dept", "7", "--name", " ", "--yes"}, "不能为空"},
{"employee missing id", []string{"user", "update", "--org-user-name", "张三", "--yes"}, "required"},
{"employee blank id", []string{"user", "update", "--user-id", " ", "--org-user-name", "张三", "--yes"}, "不能为空"},
{"employee no changes", []string{"user", "update", "--user-id", "user-1", "--org-user-name", " ", "--depts", " ", "--master-user-id", " ", "--yes"}, "至少需要一个修改项"},
{"employee invalid departments", []string{"user", "update", "--user-id", "user-1", "--depts", "bad", "--yes"}, "--depts JSON 解析失败"},
{"self no changes", []string{"user", "update-self", "--nick", " ", "--avatar-file-id", " ", "--yes"}, "至少需要一个修改项"},
{"ownness missing id", []string{"user", "update-ownness", "--ownness-text", "居家办公中", "--yes"}, "required"},
{"ownness blank id", []string{"user", "update-ownness", "--user-id", " ", "--ownness-text", "居家办公中", "--yes"}, "不能为空"},
{"ownness missing text", []string{"user", "update-ownness", "--user-id", "user-1", "--yes"}, "required"},
{"ownness blank text", []string{"user", "update-ownness", "--user-id", "user-1", "--ownness-text", " ", "--yes"}, "不能为空"},
{"account missing id", []string{"account", "update", "--nick", "小李", "--yes"}, "required"},
{"account blank id", []string{"account", "update", "--user-id", " ", "--nick", "小李", "--yes"}, "不能为空"},
{"account no changes", []string{"account", "update", "--user-id", "user-2", "--nick", " ", "--yes"}, "至少需要一个修改项"},
{"account invalid departments", []string{"account", "update", "--user-id", "user-2", "--depts", "bad", "--yes"}, "--depts JSON 解析失败"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
caller, err := runContactUpdateCommand(t, "", tt.args...)
if err == nil || !strings.Contains(err.Error(), tt.wantErr) {
t.Fatalf("error = %v, want substring %q", err, tt.wantErr)
}
if len(caller.calls) != 0 {
t.Fatalf("invalid input made %d remote call(s)", len(caller.calls))
}
})
}
}