bf9395e022
CI / license-header (push) Has been skipped
CI / e2e-dry-run (push) Has been skipped
CI / fast-gate (push) Failing after 0s
Test PR Label Logic / test-pr-labels (push) Failing after 1s
Skill Format Check / check-format (push) Failing after 2s
CI / security (push) Failing after 5s
CI / unit-test (push) Has been skipped
CI / lint (push) Has been skipped
CI / script-test (push) Has been skipped
CI / deterministic-gate (push) Has been skipped
CI / coverage (push) Has been skipped
CI / results (push) Has been cancelled
CI / deadcode (push) Has been cancelled
CI / e2e-live (push) Has been cancelled
151 lines
4.0 KiB
Go
151 lines
4.0 KiB
Go
// Copyright (c) 2026 Lark Technologies Pte. Ltd.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package task
|
|
|
|
import (
|
|
"errors"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/larksuite/cli/errs"
|
|
"github.com/larksuite/cli/internal/output"
|
|
"github.com/spf13/cobra"
|
|
|
|
"github.com/larksuite/cli/shortcuts/common"
|
|
)
|
|
|
|
func TestBuildTaskCreateBody_StructuredErrors(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
data string
|
|
summary string
|
|
due string
|
|
wantSubstr string
|
|
}{
|
|
{
|
|
name: "invalid JSON data returns validation error",
|
|
data: "not-json",
|
|
summary: "test",
|
|
wantSubstr: "--data must be a valid JSON object",
|
|
},
|
|
{
|
|
name: "missing summary returns validation error",
|
|
data: "",
|
|
summary: "",
|
|
wantSubstr: "task summary is required",
|
|
},
|
|
{
|
|
name: "invalid due time returns validation error",
|
|
data: "",
|
|
summary: "test task",
|
|
due: "not-a-valid-time",
|
|
wantSubstr: "failed to parse due time",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
cmd := &cobra.Command{}
|
|
cmd.Flags().String("data", tt.data, "")
|
|
cmd.Flags().String("summary", tt.summary, "")
|
|
cmd.Flags().String("description", "", "")
|
|
cmd.Flags().String("assignee", "", "")
|
|
cmd.Flags().String("follower", "", "")
|
|
cmd.Flags().String("due", tt.due, "")
|
|
cmd.Flags().String("tasklist-id", "", "")
|
|
cmd.Flags().String("idempotency-key", "", "")
|
|
|
|
runtime := &common.RuntimeContext{Cmd: cmd}
|
|
_, err := buildTaskCreateBody(runtime)
|
|
if err == nil {
|
|
t.Fatal("expected error, got nil")
|
|
}
|
|
|
|
var ve *errs.ValidationError
|
|
if !errors.As(err, &ve) {
|
|
t.Fatalf("error type = %T, want *errs.ValidationError; error = %v", err, err)
|
|
}
|
|
p, ok := errs.ProblemOf(err)
|
|
if !ok {
|
|
t.Fatalf("ProblemOf(%T) returned !ok", err)
|
|
}
|
|
if p.Subtype != errs.SubtypeInvalidArgument {
|
|
t.Errorf("subtype = %q, want %q", p.Subtype, errs.SubtypeInvalidArgument)
|
|
}
|
|
if got := output.ExitCodeOf(err); got != output.ExitValidation {
|
|
t.Errorf("exit code = %d, want %d", got, output.ExitValidation)
|
|
}
|
|
if !strings.Contains(err.Error(), tt.wantSubstr) {
|
|
t.Errorf("message = %q, want substring %q", err.Error(), tt.wantSubstr)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestBuildTaskUpdateBody_StructuredErrors(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
data string
|
|
summary string
|
|
due string
|
|
wantSubstr string
|
|
}{
|
|
{
|
|
name: "invalid JSON data returns validation error",
|
|
data: "not-json",
|
|
summary: "",
|
|
due: "",
|
|
wantSubstr: "--data must be a valid JSON object",
|
|
},
|
|
{
|
|
name: "no fields to update returns validation error",
|
|
data: "",
|
|
summary: "",
|
|
due: "",
|
|
wantSubstr: "no fields to update",
|
|
},
|
|
{
|
|
name: "invalid due time returns validation error",
|
|
data: "",
|
|
summary: "",
|
|
due: "not-a-valid-time",
|
|
wantSubstr: "failed to parse due time",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
cmd := &cobra.Command{}
|
|
cmd.Flags().String("data", tt.data, "")
|
|
cmd.Flags().String("summary", tt.summary, "")
|
|
cmd.Flags().String("description", "", "")
|
|
cmd.Flags().String("due", tt.due, "")
|
|
|
|
runtime := &common.RuntimeContext{Cmd: cmd}
|
|
_, err := buildTaskUpdateBody(runtime)
|
|
if err == nil {
|
|
t.Fatal("expected error, got nil")
|
|
}
|
|
|
|
var ve *errs.ValidationError
|
|
if !errors.As(err, &ve) {
|
|
t.Fatalf("error type = %T, want *errs.ValidationError; error = %v", err, err)
|
|
}
|
|
p, ok := errs.ProblemOf(err)
|
|
if !ok {
|
|
t.Fatalf("ProblemOf(%T) returned !ok", err)
|
|
}
|
|
if p.Subtype != errs.SubtypeInvalidArgument {
|
|
t.Errorf("subtype = %q, want %q", p.Subtype, errs.SubtypeInvalidArgument)
|
|
}
|
|
if got := output.ExitCodeOf(err); got != output.ExitValidation {
|
|
t.Errorf("exit code = %d, want %d", got, output.ExitValidation)
|
|
}
|
|
if !strings.Contains(err.Error(), tt.wantSubstr) {
|
|
t.Errorf("message = %q, want substring %q", err.Error(), tt.wantSubstr)
|
|
}
|
|
})
|
|
}
|
|
}
|