From 59376525d34bcfee5589f4a7a5abf75d888de54c Mon Sep 17 00:00:00 2001 From: Jimmy Praet Date: Tue, 10 Aug 2021 22:30:31 +0200 Subject: [PATCH 1/4] Filter by owner and team in API issue/pulls search --- routers/api/v1/repo/issue.go | 39 ++++++++++++++++++++++++++++++++++ templates/swagger/v1_json.tmpl | 12 +++++++++++ 2 files changed, 51 insertions(+) diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go index 172ad480318a..6112bf53f45f 100644 --- a/routers/api/v1/repo/issue.go +++ b/routers/api/v1/repo/issue.go @@ -87,6 +87,14 @@ func SearchIssues(ctx *context.APIContext) { // in: query // description: filter pulls requesting your review, default is false // type: boolean + // - name: owner + // in: query + // description: filter by owner + // type: string + // - name: team + // in: query + // description: filter by team (requires organization owner parameter to be provided) + // type: string // - name: page // in: query // description: page number of results to return (1-based) @@ -130,6 +138,37 @@ func SearchIssues(ctx *context.APIContext) { opts.Private = true opts.AllLimited = true } + if ctx.Form("owner") != "" { + owner, err := models.GetUserByName(ctx.Form("owner")) + if err != nil { + if models.IsErrUserNotExist(err) { + ctx.Error(http.StatusBadRequest, "Owner not found", err) + } else { + ctx.Error(http.StatusInternalServerError, "GetUserByName", err) + } + return + } + opts.OwnerID = owner.ID + opts.AllLimited = false + opts.AllPublic = false + opts.Collaborate = util.OptionalBoolFalse + } + if ctx.Form("team") != "" { + if ctx.Form("owner") == "" { + ctx.Error(http.StatusBadRequest, "", "Owner organisation is required for filtering on team") + return + } + team, err := models.GetTeam(opts.OwnerID, ctx.Form("team")) + if err != nil { + if models.IsErrTeamNotExist(err) { + ctx.Error(http.StatusBadRequest, "Team not found", err) + } else { + ctx.Error(http.StatusInternalServerError, "GetUserByName", err) + } + return + } + opts.TeamID = team.ID + } repoIDs, _, err := models.SearchRepositoryIDs(opts) if err != nil { diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index a1d92abec7a8..db9f64213419 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -1939,6 +1939,18 @@ "name": "review_requested", "in": "query" }, + { + "type": "string", + "description": "filter by owner", + "name": "owner", + "in": "query" + }, + { + "type": "string", + "description": "filter by team (requires organization owner parameter to be provided)", + "name": "team", + "in": "query" + }, { "type": "integer", "description": "page number of results to return (1-based)", From 7c991354f188faf396c3b0ba8a86282e79d98fcd Mon Sep 17 00:00:00 2001 From: Jimmy Praet Date: Fri, 13 Aug 2021 21:31:52 +0200 Subject: [PATCH 2/4] Add integration test --- integrations/api_issue_test.go | 25 +++++++++++++++++++++++-- models/fixtures/issue.yml | 12 ++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/integrations/api_issue_test.go b/integrations/api_issue_test.go index 74512cafa3f6..245ab76c7b6c 100644 --- a/integrations/api_issue_test.go +++ b/integrations/api_issue_test.go @@ -206,7 +206,7 @@ func TestAPISearchIssues(t *testing.T) { req = NewRequest(t, "GET", link.String()) resp = session.MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiIssues) - assert.EqualValues(t, "14", resp.Header().Get("X-Total-Count")) + assert.EqualValues(t, "15", resp.Header().Get("X-Total-Count")) assert.Len(t, apiIssues, 10) //there are more but 10 is page item limit query.Add("limit", "20") @@ -214,7 +214,7 @@ func TestAPISearchIssues(t *testing.T) { req = NewRequest(t, "GET", link.String()) resp = session.MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiIssues) - assert.Len(t, apiIssues, 14) + assert.Len(t, apiIssues, 15) query = url.Values{"assigned": {"true"}, "state": {"all"}} link.RawQuery = query.Encode() @@ -236,6 +236,27 @@ func TestAPISearchIssues(t *testing.T) { resp = session.MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiIssues) assert.Len(t, apiIssues, 2) + + query = url.Values{"owner": {"user2"}} // user + link.RawQuery = query.Encode() + req = NewRequest(t, "GET", link.String()) + resp = session.MakeRequest(t, req, http.StatusOK) + DecodeJSON(t, resp, &apiIssues) + assert.Len(t, apiIssues, 6) + + query = url.Values{"owner": {"user3"}} // organization + link.RawQuery = query.Encode() + req = NewRequest(t, "GET", link.String()) + resp = session.MakeRequest(t, req, http.StatusOK) + DecodeJSON(t, resp, &apiIssues) + assert.Len(t, apiIssues, 3) + + query = url.Values{"owner": {"user3"}, "team": {"team1"}} // organization + team + link.RawQuery = query.Encode() + req = NewRequest(t, "GET", link.String()) + resp = session.MakeRequest(t, req, http.StatusOK) + DecodeJSON(t, resp, &apiIssues) + assert.Len(t, apiIssues, 2) } func TestAPISearchIssuesWithLabels(t *testing.T) { diff --git a/models/fixtures/issue.yml b/models/fixtures/issue.yml index 946899d6ff03..d5738d5db43f 100644 --- a/models/fixtures/issue.yml +++ b/models/fixtures/issue.yml @@ -172,3 +172,15 @@ is_pull: false created_unix: 1602935696 updated_unix: 1602935696 + +- + id: 15 + repo_id: 5 + index: 1 + poster_id: 2 + name: issue in repo not linked to team1 + content: content + is_closed: false + is_pull: false + created_unix: 1602935696 + updated_unix: 1602935696 From e89b68bdb5e2d1b86b73b94bc2d7b944d98bb2e0 Mon Sep 17 00:00:00 2001 From: Jimmy Praet Date: Fri, 13 Aug 2021 21:40:59 +0200 Subject: [PATCH 3/4] Refactor ctx.FormString --- routers/api/v1/repo/issue.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go index 092b8bb6960a..e8ef2f3d05fd 100644 --- a/routers/api/v1/repo/issue.go +++ b/routers/api/v1/repo/issue.go @@ -138,8 +138,8 @@ func SearchIssues(ctx *context.APIContext) { opts.Private = true opts.AllLimited = true } - if ctx.Form("owner") != "" { - owner, err := models.GetUserByName(ctx.Form("owner")) + if ctx.FormString("owner") != "" { + owner, err := models.GetUserByName(ctx.FormString("owner")) if err != nil { if models.IsErrUserNotExist(err) { ctx.Error(http.StatusBadRequest, "Owner not found", err) @@ -153,12 +153,12 @@ func SearchIssues(ctx *context.APIContext) { opts.AllPublic = false opts.Collaborate = util.OptionalBoolFalse } - if ctx.Form("team") != "" { - if ctx.Form("owner") == "" { + if ctx.FormString("team") != "" { + if ctx.FormString("owner") == "" { ctx.Error(http.StatusBadRequest, "", "Owner organisation is required for filtering on team") return } - team, err := models.GetTeam(opts.OwnerID, ctx.Form("team")) + team, err := models.GetTeam(opts.OwnerID, ctx.FormString("team")) if err != nil { if models.IsErrTeamNotExist(err) { ctx.Error(http.StatusBadRequest, "Team not found", err) From 1fb931320843abce905b639e7d70eac5f806635e Mon Sep 17 00:00:00 2001 From: Jimmy Praet Date: Fri, 13 Aug 2021 22:00:24 +0200 Subject: [PATCH 4/4] Update num_issues in fixture --- models/fixtures/repository.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/fixtures/repository.yml b/models/fixtures/repository.yml index 492040316c10..6860d00b30e5 100644 --- a/models/fixtures/repository.yml +++ b/models/fixtures/repository.yml @@ -73,7 +73,7 @@ lower_name: repo5 name: repo5 is_private: true - num_issues: 0 + num_issues: 1 num_closed_issues: 0 num_pulls: 0 num_closed_pulls: 0