Skip to content

Commit

Permalink
Add filter by owner and team to issue/pulls search endpoint (#16662)
Browse files Browse the repository at this point in the history
* Filter by owner and team in API issue/pulls search

* Add integration test
  • Loading branch information
jpraet committed Aug 13, 2021
1 parent 3a6edd3 commit a4962a9
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 3 deletions.
25 changes: 23 additions & 2 deletions integrations/api_issue_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,15 +206,15 @@ 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")
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, 14)
assert.Len(t, apiIssues, 15)

query = url.Values{"assigned": {"true"}, "state": {"all"}}
link.RawQuery = query.Encode()
Expand All @@ -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) {
Expand Down
12 changes: 12 additions & 0 deletions models/fixtures/issue.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion models/fixtures/repository.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
39 changes: 39 additions & 0 deletions routers/api/v1/repo/issue.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -130,6 +138,37 @@ func SearchIssues(ctx *context.APIContext) {
opts.Private = true
opts.AllLimited = true
}
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)
} else {
ctx.Error(http.StatusInternalServerError, "GetUserByName", err)
}
return
}
opts.OwnerID = owner.ID
opts.AllLimited = false
opts.AllPublic = false
opts.Collaborate = util.OptionalBoolFalse
}
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.FormString("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 {
Expand Down
12 changes: 12 additions & 0 deletions templates/swagger/v1_json.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -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)",
Expand Down

0 comments on commit a4962a9

Please sign in to comment.