Use unfiltered totalCount for reviewer 'more results' display
Query aliased fields without search filter to get stable counts.
This commit is contained in:
parent
484526da77
commit
c8b1409803
2 changed files with 53 additions and 22 deletions
|
|
@ -973,6 +973,7 @@ func SuggestedReviewerActors(client *Client, repo ghrepo.Interface, prID string,
|
|||
// Fetch 10 from each source to allow cascading quota to fill from available results.
|
||||
// Use a single query that includes organization.teams - if the owner is not an org,
|
||||
// we'll get a "Could not resolve to an Organization" error which we handle gracefully.
|
||||
// We also fetch unfiltered total counts via aliases for the "X more" display.
|
||||
type responseData struct {
|
||||
Node struct {
|
||||
PullRequest struct {
|
||||
|
|
@ -996,20 +997,24 @@ func SuggestedReviewerActors(client *Client, repo ghrepo.Interface, prID string,
|
|||
} `graphql:"node(id: $id)"`
|
||||
Repository struct {
|
||||
Collaborators struct {
|
||||
TotalCount int
|
||||
Nodes []struct {
|
||||
Nodes []struct {
|
||||
Login string
|
||||
Name string
|
||||
}
|
||||
} `graphql:"collaborators(first: 10, query: $query)"`
|
||||
CollaboratorsTotalCount struct {
|
||||
TotalCount int
|
||||
} `graphql:"collaboratorsTotalCount: collaborators(first: 0)"`
|
||||
} `graphql:"repository(owner: $owner, name: $name)"`
|
||||
Organization struct {
|
||||
Teams struct {
|
||||
TotalCount int
|
||||
Nodes []struct {
|
||||
Nodes []struct {
|
||||
Slug string
|
||||
}
|
||||
} `graphql:"teams(first: 10, query: $query)"`
|
||||
TeamsTotalCount struct {
|
||||
TotalCount int
|
||||
} `graphql:"teamsTotalCount: teams(first: 0)"`
|
||||
} `graphql:"organization(login: $owner)"`
|
||||
}
|
||||
|
||||
|
|
@ -1098,9 +1103,8 @@ func SuggestedReviewerActors(client *Client, repo ghrepo.Interface, prID string,
|
|||
}
|
||||
}
|
||||
|
||||
// MoreResults is the sum of collaborators and teams total counts
|
||||
// (teams will be 0 for personal repos)
|
||||
moreResults := result.Repository.Collaborators.TotalCount + result.Organization.Teams.TotalCount
|
||||
// MoreResults uses unfiltered total counts (teams will be 0 for personal repos)
|
||||
moreResults := result.Repository.CollaboratorsTotalCount.TotalCount + result.Organization.TeamsTotalCount.TotalCount
|
||||
|
||||
return candidates, moreResults, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ func Test_Logins(t *testing.T) {
|
|||
|
||||
// mockReviewerResponse generates a GraphQL response for SuggestedReviewerActors tests.
|
||||
// It creates suggestions (s1, s2...), collaborators (c1, c2...), and teams (team1, team2...).
|
||||
// totalCollabs and totalTeams set the TotalCount fields (for "more results" calculation).
|
||||
// totalCollabs and totalTeams set the unfiltered TotalCount fields (for "more results" calculation).
|
||||
func mockReviewerResponse(suggestions, collabs, teams, totalCollabs, totalTeams int) string {
|
||||
var suggestionNodes, collabNodes, teamNodes []string
|
||||
|
||||
|
|
@ -161,11 +161,17 @@ func mockReviewerResponse(suggestions, collabs, teams, totalCollabs, totalTeams
|
|||
return fmt.Sprintf(`{
|
||||
"data": {
|
||||
"node": {"suggestedReviewerActors": {"nodes": [%s]}},
|
||||
"repository": {"collaborators": {"totalCount": %d, "nodes": [%s]}},
|
||||
"organization": {"teams": {"totalCount": %d, "nodes": [%s]}}
|
||||
"repository": {
|
||||
"collaborators": {"nodes": [%s]},
|
||||
"collaboratorsTotalCount": {"totalCount": %d}
|
||||
},
|
||||
"organization": {
|
||||
"teams": {"nodes": [%s]},
|
||||
"teamsTotalCount": {"totalCount": %d}
|
||||
}
|
||||
}
|
||||
}`, strings.Join(suggestionNodes, ","), totalCollabs, strings.Join(collabNodes, ","),
|
||||
totalTeams, strings.Join(teamNodes, ","))
|
||||
}`, strings.Join(suggestionNodes, ","), strings.Join(collabNodes, ","), totalCollabs,
|
||||
strings.Join(teamNodes, ","), totalTeams)
|
||||
}
|
||||
|
||||
func TestSuggestedReviewerActors(t *testing.T) {
|
||||
|
|
@ -234,8 +240,14 @@ func TestSuggestedReviewerActors(t *testing.T) {
|
|||
{"isAuthor": false, "reviewer": {"__typename": "User", "login": "s1", "name": "S1"}},
|
||||
{"isAuthor": false, "reviewer": {"__typename": "User", "login": "s2", "name": "S2"}}
|
||||
]}},
|
||||
"repository": {"collaborators": {"totalCount": 5, "nodes": [{"login": "c1", "name": "C1"}]}},
|
||||
"organization": {"teams": {"totalCount": 3, "nodes": [{"slug": "team1"}]}}
|
||||
"repository": {
|
||||
"collaborators": {"nodes": [{"login": "c1", "name": "C1"}]},
|
||||
"collaboratorsTotalCount": {"totalCount": 5}
|
||||
},
|
||||
"organization": {
|
||||
"teams": {"nodes": [{"slug": "team1"}]},
|
||||
"teamsTotalCount": {"totalCount": 3}
|
||||
}
|
||||
}
|
||||
}`))
|
||||
},
|
||||
|
|
@ -254,11 +266,17 @@ func TestSuggestedReviewerActors(t *testing.T) {
|
|||
"node": {"suggestedReviewerActors": {"nodes": [
|
||||
{"isAuthor": false, "reviewer": {"__typename": "User", "login": "shareduser", "name": "Shared"}}
|
||||
]}},
|
||||
"repository": {"collaborators": {"totalCount": 10, "nodes": [
|
||||
{"login": "shareduser", "name": "Shared"},
|
||||
{"login": "c1", "name": "C1"}
|
||||
]}},
|
||||
"organization": {"teams": {"totalCount": 5, "nodes": [{"slug": "team1"}]}}
|
||||
"repository": {
|
||||
"collaborators": {"nodes": [
|
||||
{"login": "shareduser", "name": "Shared"},
|
||||
{"login": "c1", "name": "C1"}
|
||||
]},
|
||||
"collaboratorsTotalCount": {"totalCount": 10}
|
||||
},
|
||||
"organization": {
|
||||
"teams": {"nodes": [{"slug": "team1"}]},
|
||||
"teamsTotalCount": {"totalCount": 5}
|
||||
}
|
||||
}
|
||||
}`))
|
||||
},
|
||||
|
|
@ -276,7 +294,10 @@ func TestSuggestedReviewerActors(t *testing.T) {
|
|||
"node": {"suggestedReviewerActors": {"nodes": [
|
||||
{"isAuthor": false, "reviewer": {"__typename": "User", "login": "s1", "name": "S1"}}
|
||||
]}},
|
||||
"repository": {"collaborators": {"totalCount": 3, "nodes": [{"login": "c1", "name": "C1"}]}},
|
||||
"repository": {
|
||||
"collaborators": {"nodes": [{"login": "c1", "name": "C1"}]},
|
||||
"collaboratorsTotalCount": {"totalCount": 3}
|
||||
},
|
||||
"organization": null
|
||||
},
|
||||
"errors": [{"message": "Could not resolve to an Organization with the login of 'OWNER'."}]
|
||||
|
|
@ -297,8 +318,14 @@ func TestSuggestedReviewerActors(t *testing.T) {
|
|||
{"isAuthor": false, "reviewer": {"__typename": "Bot", "login": "copilot-pull-request-reviewer"}},
|
||||
{"isAuthor": false, "reviewer": {"__typename": "User", "login": "s1", "name": "S1"}}
|
||||
]}},
|
||||
"repository": {"collaborators": {"totalCount": 5, "nodes": []}},
|
||||
"organization": {"teams": {"totalCount": 0, "nodes": []}}
|
||||
"repository": {
|
||||
"collaborators": {"nodes": []},
|
||||
"collaboratorsTotalCount": {"totalCount": 5}
|
||||
},
|
||||
"organization": {
|
||||
"teams": {"nodes": []},
|
||||
"teamsTotalCount": {"totalCount": 0}
|
||||
}
|
||||
}
|
||||
}`))
|
||||
},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue