240 lines
7.5 KiB
Go
240 lines
7.5 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"
|
|
"os"
|
|
"reflect"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/DingTalk-Real-AI/dingtalk-workspace-cli/pkg/edition"
|
|
)
|
|
|
|
type contactEnterpriseCall struct {
|
|
productID string
|
|
toolName string
|
|
args map[string]any
|
|
}
|
|
|
|
type contactEnterpriseCaller struct {
|
|
calls []contactEnterpriseCall
|
|
}
|
|
|
|
func (c *contactEnterpriseCaller) CallTool(_ context.Context, productID, toolName string, args map[string]any) (*edition.ToolResult, error) {
|
|
c.calls = append(c.calls, contactEnterpriseCall{
|
|
productID: productID,
|
|
toolName: toolName,
|
|
args: args,
|
|
})
|
|
return &edition.ToolResult{Content: []edition.ContentBlock{{Type: "text", Text: `{}`}}}, nil
|
|
}
|
|
|
|
func (*contactEnterpriseCaller) Format() string { return "json" }
|
|
func (*contactEnterpriseCaller) DryRun() bool { return false }
|
|
func (*contactEnterpriseCaller) Fields() string { return "" }
|
|
func (*contactEnterpriseCaller) JQ() string { return "" }
|
|
|
|
func runContactEnterpriseCommand(t *testing.T, 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...)
|
|
|
|
cmd := newContactCommand()
|
|
cmd.SilenceErrors = true
|
|
cmd.SilenceUsage = true
|
|
cmd.SetArgs(args)
|
|
return caller, cmd.Execute()
|
|
}
|
|
|
|
func TestCrossPlatformCoverageContactEnterpriseCommandsExposeExpectedFlags(t *testing.T) {
|
|
root := newContactCommand()
|
|
cases := []struct {
|
|
path []string
|
|
flags []string
|
|
}{
|
|
{[]string{"org", "create"}, []string{"org-name", "creator-username"}},
|
|
{[]string{"user", "invite"}, []string{"org-user-name", "org-user-mobile", "depts"}},
|
|
{[]string{"account", "create"}, []string{"org-user-name", "login-id", "org-user-mobile", "email", "dept-ids", "send-pwd-via-sms"}},
|
|
}
|
|
for _, tc := range cases {
|
|
cmd := requireWukongSyncCommand(t, root, tc.path...)
|
|
requireWukongSyncFlags(t, cmd, tc.flags...)
|
|
}
|
|
}
|
|
|
|
func TestCrossPlatformCoverageContactEnterpriseCommandsMapMCPArguments(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
args []string
|
|
toolName string
|
|
wantArgs map[string]any
|
|
}{
|
|
{
|
|
name: "create organization",
|
|
args: []string{"org", "create", "--org-name", "测试企业", "--creator-username", "张三"},
|
|
toolName: "org_create",
|
|
wantArgs: map[string]any{
|
|
"orgName": "测试企业",
|
|
"creatorUsername": "张三",
|
|
},
|
|
},
|
|
{
|
|
name: "invite employee",
|
|
args: []string{"user", "invite", "--org-user-name", " 李四 ", "--org-user-mobile", " 13800138000 ", "--depts", `[{"deptId":1}]`},
|
|
toolName: "add_employee",
|
|
wantArgs: map[string]any{
|
|
"orgUserName": "李四",
|
|
"orgUserMobile": "13800138000",
|
|
"depts": []map[string]any{{"deptId": float64(1)}},
|
|
},
|
|
},
|
|
{
|
|
name: "create enterprise account",
|
|
args: []string{
|
|
"account", "create",
|
|
"--org-user-name", " 王五 ",
|
|
"--login-id", " wangwu001 ",
|
|
"--org-user-mobile", " 13900139000 ",
|
|
"--email", " wangwu@example.com ",
|
|
"--dept-ids", "1, 2,3",
|
|
"--send-pwd-via-sms",
|
|
},
|
|
toolName: "exclusive_account_create",
|
|
wantArgs: map[string]any{
|
|
"orgUserName": "王五",
|
|
"loginId": "wangwu001",
|
|
"orgUserMobile": "13900139000",
|
|
"email": "wangwu@example.com",
|
|
"deptIds": []int64{1, 2, 3},
|
|
"sendPwdViaSms": true,
|
|
},
|
|
},
|
|
{
|
|
name: "create enterprise account without optional send flag",
|
|
args: []string{"account", "create", "--org-user-name", "王五", "--login-id", "wangwu001"},
|
|
toolName: "exclusive_account_create",
|
|
wantArgs: map[string]any{
|
|
"orgUserName": "王五",
|
|
"loginId": "wangwu001",
|
|
},
|
|
},
|
|
{
|
|
name: "create enterprise account with explicit false send flag",
|
|
args: []string{"account", "create", "--org-user-name", "王五", "--login-id", "wangwu001", "--send-pwd-via-sms=false"},
|
|
toolName: "exclusive_account_create",
|
|
wantArgs: map[string]any{
|
|
"orgUserName": "王五",
|
|
"loginId": "wangwu001",
|
|
"sendPwdViaSms": false,
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
caller, err := runContactEnterpriseCommand(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 TestCrossPlatformCoverageContactUserInviteRejectsInvalidDepartmentsJSON(t *testing.T) {
|
|
caller, err := runContactEnterpriseCommand(t,
|
|
"user", "invite",
|
|
"--org-user-name", "张三",
|
|
"--org-user-mobile", "13800138000",
|
|
"--depts", "not-json",
|
|
)
|
|
if err == nil || !strings.Contains(err.Error(), "--depts JSON 解析失败") {
|
|
t.Fatalf("error = %v, want departments JSON validation", err)
|
|
}
|
|
if len(caller.calls) != 0 {
|
|
t.Fatalf("invalid input made %d remote call(s)", len(caller.calls))
|
|
}
|
|
}
|
|
|
|
func TestCrossPlatformCoverageContactAccountCreateRejectsInvalidDepartmentIDs(t *testing.T) {
|
|
for _, deptIDs := range []string{"1,not-an-id,3", "1,,3", " "} {
|
|
t.Run(deptIDs, func(t *testing.T) {
|
|
caller, err := runContactEnterpriseCommand(t,
|
|
"account", "create",
|
|
"--org-user-name", "张三",
|
|
"--login-id", "zhangsan001",
|
|
"--dept-ids", deptIDs,
|
|
)
|
|
if err == nil || !strings.Contains(err.Error(), "--dept-ids 解析失败") {
|
|
t.Fatalf("error = %v, want department ID validation", err)
|
|
}
|
|
if len(caller.calls) != 0 {
|
|
t.Fatalf("invalid input made %d remote call(s)", len(caller.calls))
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCrossPlatformCoverageContactOrgAndAccountCreateRejectWhitespaceIdentityFlags(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
args []string
|
|
}{
|
|
{"organization name", []string{"org", "create", "--org-name", " ", "--creator-username", "张三"}},
|
|
{"organization creator", []string{"org", "create", "--org-name", "测试企业", "--creator-username", " "}},
|
|
{"account user name", []string{"account", "create", "--org-user-name", " ", "--login-id", "zhangsan001"}},
|
|
{"account login ID", []string{"account", "create", "--org-user-name", "张三", "--login-id", " "}},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
caller, err := runContactEnterpriseCommand(t, tt.args...)
|
|
if err == nil || !strings.Contains(err.Error(), "不能为空") {
|
|
t.Fatalf("error = %v, want non-blank identity validation", err)
|
|
}
|
|
if len(caller.calls) != 0 {
|
|
t.Fatalf("blank input made %d remote call(s)", len(caller.calls))
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCrossPlatformCoverageContactEnterpriseCommandsRequireCoreIdentityFlags(t *testing.T) {
|
|
tests := [][]string{
|
|
{"org", "create", "--org-name", "测试企业"},
|
|
{"user", "invite", "--org-user-name", "张三"},
|
|
{"account", "create", "--org-user-name", "张三"},
|
|
}
|
|
for _, args := range tests {
|
|
caller, err := runContactEnterpriseCommand(t, args...)
|
|
if err == nil {
|
|
t.Fatalf("%v returned nil error, want required-flag validation", args)
|
|
}
|
|
if len(caller.calls) != 0 {
|
|
t.Fatalf("%v made %d remote call(s)", args, len(caller.calls))
|
|
}
|
|
}
|
|
}
|