Add filter by owner and team to issue/pulls search endpoint (#16662)
* Filter by owner and team in API issue/pulls search * Add integration test
This commit is contained in:
		
							parent
							
								
									3a6edd3685
								
							
						
					
					
						commit
						a4962a9440
					
				| @ -206,7 +206,7 @@ func TestAPISearchIssues(t *testing.T) { | |||||||
| 	req = NewRequest(t, "GET", link.String()) | 	req = NewRequest(t, "GET", link.String()) | ||||||
| 	resp = session.MakeRequest(t, req, http.StatusOK) | 	resp = session.MakeRequest(t, req, http.StatusOK) | ||||||
| 	DecodeJSON(t, resp, &apiIssues) | 	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
 | 	assert.Len(t, apiIssues, 10) //there are more but 10 is page item limit
 | ||||||
| 
 | 
 | ||||||
| 	query.Add("limit", "20") | 	query.Add("limit", "20") | ||||||
| @ -214,7 +214,7 @@ func TestAPISearchIssues(t *testing.T) { | |||||||
| 	req = NewRequest(t, "GET", link.String()) | 	req = NewRequest(t, "GET", link.String()) | ||||||
| 	resp = session.MakeRequest(t, req, http.StatusOK) | 	resp = session.MakeRequest(t, req, http.StatusOK) | ||||||
| 	DecodeJSON(t, resp, &apiIssues) | 	DecodeJSON(t, resp, &apiIssues) | ||||||
| 	assert.Len(t, apiIssues, 14) | 	assert.Len(t, apiIssues, 15) | ||||||
| 
 | 
 | ||||||
| 	query = url.Values{"assigned": {"true"}, "state": {"all"}} | 	query = url.Values{"assigned": {"true"}, "state": {"all"}} | ||||||
| 	link.RawQuery = query.Encode() | 	link.RawQuery = query.Encode() | ||||||
| @ -236,6 +236,27 @@ func TestAPISearchIssues(t *testing.T) { | |||||||
| 	resp = session.MakeRequest(t, req, http.StatusOK) | 	resp = session.MakeRequest(t, req, http.StatusOK) | ||||||
| 	DecodeJSON(t, resp, &apiIssues) | 	DecodeJSON(t, resp, &apiIssues) | ||||||
| 	assert.Len(t, apiIssues, 2) | 	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) { | func TestAPISearchIssuesWithLabels(t *testing.T) { | ||||||
|  | |||||||
| @ -172,3 +172,15 @@ | |||||||
|   is_pull: false |   is_pull: false | ||||||
|   created_unix: 1602935696 |   created_unix: 1602935696 | ||||||
|   updated_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 | ||||||
|  | |||||||
| @ -73,7 +73,7 @@ | |||||||
|   lower_name: repo5 |   lower_name: repo5 | ||||||
|   name: repo5 |   name: repo5 | ||||||
|   is_private: true |   is_private: true | ||||||
|   num_issues: 0 |   num_issues: 1 | ||||||
|   num_closed_issues: 0 |   num_closed_issues: 0 | ||||||
|   num_pulls: 0 |   num_pulls: 0 | ||||||
|   num_closed_pulls: 0 |   num_closed_pulls: 0 | ||||||
|  | |||||||
| @ -87,6 +87,14 @@ func SearchIssues(ctx *context.APIContext) { | |||||||
| 	//   in: query
 | 	//   in: query
 | ||||||
| 	//   description: filter pulls requesting your review, default is false
 | 	//   description: filter pulls requesting your review, default is false
 | ||||||
| 	//   type: boolean
 | 	//   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
 | 	// - name: page
 | ||||||
| 	//   in: query
 | 	//   in: query
 | ||||||
| 	//   description: page number of results to return (1-based)
 | 	//   description: page number of results to return (1-based)
 | ||||||
| @ -130,6 +138,37 @@ func SearchIssues(ctx *context.APIContext) { | |||||||
| 		opts.Private = true | 		opts.Private = true | ||||||
| 		opts.AllLimited = 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) | 	repoIDs, _, err := models.SearchRepositoryIDs(opts) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
|  | |||||||
| @ -1939,6 +1939,18 @@ | |||||||
|             "name": "review_requested", |             "name": "review_requested", | ||||||
|             "in": "query" |             "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", |             "type": "integer", | ||||||
|             "description": "page number of results to return (1-based)", |             "description": "page number of results to return (1-based)", | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user