|
4 | 4 | package service |
5 | 5 |
|
6 | 6 | import ( |
| 7 | + "errors" |
7 | 8 | "strings" |
8 | 9 | "testing" |
9 | 10 |
|
| 11 | + "github.com/larksuite/cli/errs" |
10 | 12 | "github.com/larksuite/cli/internal/cmdutil" |
11 | 13 | "github.com/larksuite/cli/internal/meta" |
12 | 14 | "github.com/spf13/cobra" |
@@ -574,3 +576,51 @@ func TestServiceMethod_TypedFlag_HelpShowsBounds(t *testing.T) { |
574 | 576 | t.Errorf("flag usage should carry bounds, got %q", fl.Usage) |
575 | 577 | } |
576 | 578 | } |
| 579 | + |
| 580 | +// The missing-required hint must name both recovery paths — the typed flag and |
| 581 | +// the --params fallback — so a reader who only knows one input style can |
| 582 | +// proceed without a round-trip through schema. |
| 583 | +func TestServiceMethod_MissingRequired_HintNamesFlagAndParams(t *testing.T) { |
| 584 | + f, _, _, _ := cmdutil.TestFactory(t, testConfig) |
| 585 | + cmd := NewCmdServiceMethod(f, imSpec(), imChatMembersCreate(), "create", "chat.members", nil) |
| 586 | + cmd.SetArgs([]string{"--data", `{"id_list":["ou_x"]}`, "--dry-run"}) |
| 587 | + |
| 588 | + err := cmd.Execute() |
| 589 | + var ve *errs.ValidationError |
| 590 | + if !errors.As(err, &ve) { |
| 591 | + t.Fatalf("expected *errs.ValidationError, got %T: %v", err, err) |
| 592 | + } |
| 593 | + for _, want := range []string{"--chat-id", `--params '{"chat_id": "<value>"}'`, "lark-cli schema im.chat.members.create"} { |
| 594 | + if !strings.Contains(ve.Hint, want) { |
| 595 | + t.Errorf("hint %q should contain %q", ve.Hint, want) |
| 596 | + } |
| 597 | + } |
| 598 | +} |
| 599 | + |
| 600 | +// A params-only required field (kebab name claimed by the standard --format |
| 601 | +// flag) has no typed flag to offer: the hint must give only the --params form, |
| 602 | +// never steer the reader to the colliding flag. |
| 603 | +func TestServiceMethod_MissingRequired_ParamsOnlyHintSkipsFlag(t *testing.T) { |
| 604 | + method := meta.FromMap(map[string]interface{}{ |
| 605 | + "path": "messages", |
| 606 | + "httpMethod": "GET", |
| 607 | + "parameters": map[string]interface{}{ |
| 608 | + "format": map[string]interface{}{"type": "string", "location": "query", "required": true}, |
| 609 | + }, |
| 610 | + }) |
| 611 | + f, _, _, _ := cmdutil.TestFactory(t, testConfig) |
| 612 | + cmd := NewCmdServiceMethod(f, imSpec(), method, "list", "messages", nil) |
| 613 | + cmd.SetArgs([]string{"--dry-run"}) |
| 614 | + |
| 615 | + err := cmd.Execute() |
| 616 | + var ve *errs.ValidationError |
| 617 | + if !errors.As(err, &ve) { |
| 618 | + t.Fatalf("expected *errs.ValidationError, got %T: %v", err, err) |
| 619 | + } |
| 620 | + if !strings.Contains(ve.Hint, `--params '{"format": "<value>"}'`) { |
| 621 | + t.Errorf("hint %q should carry the --params form", ve.Hint) |
| 622 | + } |
| 623 | + if strings.Contains(ve.Hint, "set --format") { |
| 624 | + t.Errorf("hint %q must not steer to the colliding --format flag", ve.Hint) |
| 625 | + } |
| 626 | +} |
0 commit comments