diff --git a/internal/cli/dailyops_commands_test.go b/internal/cli/dailyops_commands_test.go index 187270d..9585304 100644 --- a/internal/cli/dailyops_commands_test.go +++ b/internal/cli/dailyops_commands_test.go @@ -220,6 +220,52 @@ func TestLabelsMilestonesReleasesList(t *testing.T) { } } +// TestStateAllSendsExplicitParam 是 #33 的回歸測試:issues/milestones +// 端點省略 state 時 API 預設 open,closed 項目會漏列,因此 --state all +// 必須明確帶 state=all;pulls 端點雖省略時也回全部,同樣明確帶上。 +func TestStateAllSendsExplicitParam(t *testing.T) { + cases := []struct { + args []string + resp string + wantOut string + }{ + { + args: []string{"issues", "list", "--repo", "a/b", "--state", "all"}, + resp: `[{"number":30,"title":"open","state":"open","user":{"login":"ceo"},"updated_at":"t"},{"number":12,"title":"closed","state":"closed","user":{"login":"ceo"},"updated_at":"t"}]`, + wantOut: `"title":"closed"`, + }, + { + args: []string{"pulls", "list", "--repo", "a/b", "--state", "all"}, + resp: `[{"number":5,"title":"open PR","state":"open","user":{"login":"ceo"},"head":{"ref":"f"},"base":{"ref":"main"},"updated_at":"t"},{"number":2,"title":"closed PR","state":"closed","user":{"login":"ceo"},"head":{"ref":"f2"},"base":{"ref":"main"},"updated_at":"t"}]`, + wantOut: `"title":"closed PR"`, + }, + { + args: []string{"milestones", "list", "--repo", "a/b", "--state", "all"}, + resp: `[{"title":"v2","state":"open","description":"","due_on":""},{"title":"v1","state":"closed","description":"","due_on":""}]`, + wantOut: `"title":"v1"`, + }, + } + for _, tc := range cases { + t.Run(strings.Join(tc.args, " "), func(t *testing.T) { + var gotQuery string + run := opsTestServer(t, func(w http.ResponseWriter, r *http.Request) { + gotQuery = r.URL.RawQuery + fmt.Fprint(w, tc.resp) + }) + stdout, _, code := run(tc.args...) + if code != 0 { + t.Fatalf("%v 應回 0,得到 %d", tc.args, code) + } + if !strings.Contains(gotQuery, "state=all") { + t.Errorf("%v 應明確帶 state=all(省略時 issues/milestones 端點預設 open),得到查詢 %q", tc.args, gotQuery) + } + if !strings.Contains(stdout, tc.wantOut) { + t.Errorf("%v 輸出應含 closed 項目 %s,得到:%s", tc.args, tc.wantOut, stdout) + } + }) + } +} + // TestAPIDirectPassthrough 驗證 teai api 原樣輸出、GET 免 --yes、 // POST 未帶 --yes 被擋。 func TestAPIDirectPassthrough(t *testing.T) { diff --git a/internal/dailyops/dailyops.go b/internal/dailyops/dailyops.go index ece6ceb..f50fecc 100644 --- a/internal/dailyops/dailyops.go +++ b/internal/dailyops/dailyops.go @@ -170,10 +170,10 @@ func (o *Ops) ListIssues(ctx context.Context, owner, repo, state string) ([]Issu if state == "" { state = "open" } + // state 一律明確傳給 API:issues/milestones 端點省略 state 時預設 + // open(#33),closed 項目會漏列;all 也不能省略。 extra := url.Values{} - if state != "all" { - extra.Set("state", state) - } + extra.Set("state", state) // type=issues:排除 PR(PR 在此端點帶 pull_request 欄位)。 extra.Set("type", "issues") var issues []Issue @@ -246,10 +246,10 @@ func (o *Ops) ListPulls(ctx context.Context, owner, repo, state string) ([]Pull, if state == "" { state = "open" } + // state 一律明確傳給 API:pulls 端點省略 state 時雖回全部,仍明確 + // 帶上,避免依賴端點預設值(#33)。 extra := url.Values{} - if state != "all" { - extra.Set("state", state) - } + extra.Set("state", state) var pulls []Pull if err := o.Client.ListAll(ctx, repoPath(owner, repo)+"/pulls", gitea.ListOptions{Extra: extra}, &pulls); err != nil { return nil, err @@ -320,10 +320,10 @@ func (o *Ops) ListMilestones(ctx context.Context, owner, repo, state string) ([] if state == "" { state = "open" } + // state 一律明確傳給 API:milestones 端點省略 state 時預設 open + // (#33),closed 項目會漏列。 extra := url.Values{} - if state != "all" { - extra.Set("state", state) - } + extra.Set("state", state) var ms []Milestone if err := o.Client.ListAll(ctx, repoPath(owner, repo)+"/milestones", gitea.ListOptions{Extra: extra}, &ms); err != nil { return nil, err