Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 48 additions & 9 deletions shortcuts/im/builders_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,42 @@ func newTestRuntimeContext(t *testing.T, stringFlags map[string]string, boolFlag
t.Helper()

cmd := &cobra.Command{Use: "test"}
cmd.Flags().Int("page-limit", 20, "")
for name := range stringFlags {
if name == "page-limit" {
continue
}
cmd.Flags().String(name, "", "")
}
for name := range boolFlags {
cmd.Flags().Bool(name, false, "")
}
if err := cmd.ParseFlags(nil); err != nil {
t.Fatalf("ParseFlags() error = %v", err)
}
for name, val := range stringFlags {
if err := cmd.Flags().Set(name, val); err != nil {
t.Fatalf("Flags().Set(%q) error = %v", name, err)
}
}
for name, val := range boolFlags {
if err := cmd.Flags().Set(name, map[bool]string{true: "true", false: "false"}[val]); err != nil {
t.Fatalf("Flags().Set(%q) error = %v", name, err)
}
}
return &common.RuntimeContext{Cmd: cmd}
}

func newMessagesSearchTestRuntimeContext(t *testing.T, stringFlags map[string]string, boolFlags map[string]bool) *common.RuntimeContext {
t.Helper()

cmd := &cobra.Command{Use: "test"}
cmd.Flags().Int("page-size", 20, "")
cmd.Flags().Int("page-limit", 20, "")
for name := range stringFlags {
if name == "page-size" || name == "page-limit" {
continue
}
cmd.Flags().String(name, "", "")
Comment thread
YangJunzhou-01 marked this conversation as resolved.
}
for name := range boolFlags {
Expand Down Expand Up @@ -460,7 +495,7 @@ func TestShortcutValidateBranches(t *testing.T) {
})

t.Run("ImMessagesSearch invalid page size", func(t *testing.T) {
runtime := newTestRuntimeContext(t, map[string]string{
runtime := newMessagesSearchTestRuntimeContext(t, map[string]string{
"query": "incident",
"page-size": "0",
}, nil)
Expand All @@ -471,7 +506,7 @@ func TestShortcutValidateBranches(t *testing.T) {
})

t.Run("ImMessagesSearch invalid page limit", func(t *testing.T) {
runtime := newTestRuntimeContext(t, map[string]string{
runtime := newMessagesSearchTestRuntimeContext(t, map[string]string{
"query": "incident",
"page-limit": "41",
}, nil)
Expand All @@ -482,7 +517,7 @@ func TestShortcutValidateBranches(t *testing.T) {
})

t.Run("ImMessagesSearch invalid sender id", func(t *testing.T) {
runtime := newTestRuntimeContext(t, map[string]string{
runtime := newMessagesSearchTestRuntimeContext(t, map[string]string{
"sender": "user_1",
}, nil)
err := ImMessagesSearch.Validate(context.Background(), runtime)
Expand All @@ -492,7 +527,7 @@ func TestShortcutValidateBranches(t *testing.T) {
})

t.Run("ImMessagesSearch invalid chat id", func(t *testing.T) {
runtime := newTestRuntimeContext(t, map[string]string{
runtime := newMessagesSearchTestRuntimeContext(t, map[string]string{
"chat-id": "bad_chat",
}, nil)
err := ImMessagesSearch.Validate(context.Background(), runtime)
Expand All @@ -502,7 +537,7 @@ func TestShortcutValidateBranches(t *testing.T) {
})

t.Run("ImMessagesSearch invalid time range", func(t *testing.T) {
runtime := newTestRuntimeContext(t, map[string]string{
runtime := newMessagesSearchTestRuntimeContext(t, map[string]string{
"start": "2025-01-02T00:00:00Z",
"end": "2025-01-01T00:00:00Z",
}, nil)
Expand All @@ -515,7 +550,7 @@ func TestShortcutValidateBranches(t *testing.T) {

func TestMessagesSearchPaginationConfig(t *testing.T) {
t.Run("default single page", func(t *testing.T) {
runtime := newTestRuntimeContext(t, nil, nil)
runtime := newMessagesSearchTestRuntimeContext(t, nil, nil)
autoPaginate, pageLimit := messagesSearchPaginationConfig(runtime)
if autoPaginate {
t.Fatal("messagesSearchPaginationConfig() autoPaginate = true, want false")
Expand All @@ -526,7 +561,7 @@ func TestMessagesSearchPaginationConfig(t *testing.T) {
})

t.Run("page all uses max limit", func(t *testing.T) {
runtime := newTestRuntimeContext(t, nil, map[string]bool{
runtime := newMessagesSearchTestRuntimeContext(t, nil, map[string]bool{
"page-all": true,
})
autoPaginate, pageLimit := messagesSearchPaginationConfig(runtime)
Expand All @@ -539,9 +574,13 @@ func TestMessagesSearchPaginationConfig(t *testing.T) {
})

t.Run("explicit page limit enables auto pagination", func(t *testing.T) {
runtime := newTestRuntimeContext(t, map[string]string{
runtime := newMessagesSearchTestRuntimeContext(t, map[string]string{
"query": "incident",
"page-limit": "3",
}, nil)
if err := ImMessagesSearch.Validate(context.Background(), runtime); err != nil {
t.Fatalf("ImMessagesSearch.Validate() error = %v, want valid explicit --page-limit", err)
}
autoPaginate, pageLimit := messagesSearchPaginationConfig(runtime)
Comment thread
coderabbitai[bot] marked this conversation as resolved.
if !autoPaginate {
t.Fatal("messagesSearchPaginationConfig() autoPaginate = false, want true")
Expand Down Expand Up @@ -585,7 +624,7 @@ func TestShortcutDryRunShapes(t *testing.T) {
})

t.Run("ImMessagesSearch dry run uses messages search endpoint", func(t *testing.T) {
runtime := newTestRuntimeContext(t, map[string]string{
runtime := newMessagesSearchTestRuntimeContext(t, map[string]string{
"query": "incident",
"page-size": "51",
"page-token": "next_page",
Expand Down
6 changes: 3 additions & 3 deletions shortcuts/im/coverage_additional_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ func TestResolveChatIDForMessagesList(t *testing.T) {

func TestBuildMessagesSearchRequest(t *testing.T) {
t.Run("valid request", func(t *testing.T) {
runtime := newTestRuntimeContext(t, map[string]string{
runtime := newMessagesSearchTestRuntimeContext(t, map[string]string{
"query": "hello",
"chat-id": "oc_1,oc_2",
"sender": "ou_1,ou_2",
Expand Down Expand Up @@ -374,7 +374,7 @@ func TestBuildMessagesSearchRequest(t *testing.T) {
})

t.Run("start later than end", func(t *testing.T) {
runtime := newTestRuntimeContext(t, map[string]string{
runtime := newMessagesSearchTestRuntimeContext(t, map[string]string{
"start": "2026-03-03T00:00:00+08:00",
"end": "2026-03-02T00:00:00+08:00",
}, nil)
Expand All @@ -385,7 +385,7 @@ func TestBuildMessagesSearchRequest(t *testing.T) {
})

t.Run("invalid sender id", func(t *testing.T) {
runtime := newTestRuntimeContext(t, map[string]string{
runtime := newMessagesSearchTestRuntimeContext(t, map[string]string{
"sender": "bad_sender",
}, nil)
_, err := buildMessagesSearchRequest(runtime)
Expand Down
29 changes: 10 additions & 19 deletions shortcuts/im/im_messages_search.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"io"
"net/http"
"strconv"
"strings"

"github.com/larksuite/cli/internal/output"
"github.com/larksuite/cli/shortcuts/common"
Expand Down Expand Up @@ -45,7 +44,7 @@ var ImMessagesSearch = common.Shortcut{
{Name: "is-at-me", Type: "bool", Desc: "only messages that @me"},
{Name: "start", Desc: "start time(ISO 8601) with local timezone offset (e.g. 2026-03-24T00:00:00+08:00)"},
{Name: "end", Desc: "end time(ISO 8601) with local timezone offset (e.g. 2026-03-25T23:59:59+08:00)"},
{Name: "page-size", Default: "20", Desc: "page size (1-50)"},
{Name: "page-size", Type: "int", Default: "20", Desc: "page size (1-50)"},
{Name: "page-token", Desc: "page token"},
{Name: "page-all", Type: "bool", Desc: "automatically paginate search results"},
{Name: "page-limit", Type: "int", Default: "20", Desc: "max search pages when auto-pagination is enabled (default 20, max 40)"},
Expand Down Expand Up @@ -248,13 +247,11 @@ func buildMessagesSearchRequest(runtime *common.RuntimeContext) (*messagesSearch
excludeSenderTypeFlag := runtime.Str("exclude-sender-type")
startFlag := runtime.Str("start")
endFlag := runtime.Str("end")
pageSizeStr := runtime.Str("page-size")
pageToken := runtime.Str("page-token")
pageLimitStr := strings.TrimSpace(runtime.Str("page-limit"))

if runtime.Cmd != nil && runtime.Cmd.Flags().Changed("page-limit") {
pageLimit, err := strconv.Atoi(pageLimitStr)
if err != nil || pageLimit < 1 || pageLimit > messagesSearchMaxPageLimit {
pageLimit := runtime.Int("page-limit")
if pageLimit < 1 || pageLimit > messagesSearchMaxPageLimit {
return nil, output.ErrValidation("--page-limit must be an integer between 1 and 40")
}
}
Expand Down Expand Up @@ -333,16 +330,12 @@ func buildMessagesSearchRequest(runtime *common.RuntimeContext) (*messagesSearch
body["filter"] = filter
}

pageSize := messagesSearchDefaultPageSize
if pageSizeStr != "" {
n, err := strconv.Atoi(pageSizeStr)
if err != nil || n < 1 {
return nil, output.ErrValidation("--page-size must be an integer between 1 and 50")
}
if n > messagesSearchMaxPageSize {
n = messagesSearchMaxPageSize
}
pageSize = n
pageSize := runtime.Int("page-size")
if pageSize < 1 {
return nil, output.ErrValidation("--page-size must be an integer between 1 and 50")
}
if pageSize > messagesSearchMaxPageSize {
pageSize = messagesSearchMaxPageSize
}

params := larkcore.QueryParams{
Expand All @@ -366,9 +359,7 @@ func messagesSearchPaginationConfig(runtime *common.RuntimeContext) (autoPaginat

pageLimit = messagesSearchDefaultPageLimit
if runtime.Cmd != nil && runtime.Cmd.Flags().Changed("page-limit") {
if n, err := strconv.Atoi(strings.TrimSpace(runtime.Str("page-limit"))); err == nil && n > 0 {
pageLimit = min(n, messagesSearchMaxPageLimit)
}
pageLimit = min(runtime.Int("page-limit"), messagesSearchMaxPageLimit)
} else if runtime.Bool("page-all") {
pageLimit = messagesSearchMaxPageLimit
}
Expand Down
9 changes: 3 additions & 6 deletions shortcuts/im/im_messages_search_execute_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,12 @@ func newMessagesSearchRuntime(t *testing.T, stringFlags map[string]string, boolF
runtime := newBotShortcutRuntime(t, rt)
cmd := &cobra.Command{Use: "test"}

stringFlagNames := []string{
"query",
"page-size",
"page-token",
"page-limit",
}
stringFlagNames := []string{"query", "page-token"}
for _, name := range stringFlagNames {
cmd.Flags().String(name, "", "")
}
cmd.Flags().Int("page-size", 20, "")
cmd.Flags().Int("page-limit", 20, "")
boolFlagNames := []string{"page-all"}
for _, name := range boolFlagNames {
cmd.Flags().Bool(name, false, "")
Expand Down
Loading