[API] expose repo.GetReviewers() & repo.GetAssignees() (#16168)
* API: expose repo.GetReviewers() & repo.GetAssignees() * Add tests * fix unrelated swagger query typerelease/v1.15
parent
0db1048c3a
commit
b3fbd37e99
|
@ -494,3 +494,31 @@ func TestAPIRepoTransfer(t *testing.T) {
|
||||||
repo = models.AssertExistsAndLoadBean(t, &models.Repository{ID: repo.ID}).(*models.Repository)
|
repo = models.AssertExistsAndLoadBean(t, &models.Repository{ID: repo.ID}).(*models.Repository)
|
||||||
_ = models.DeleteRepository(user, repo.OwnerID, repo.ID)
|
_ = models.DeleteRepository(user, repo.OwnerID, repo.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAPIRepoGetReviewers(t *testing.T) {
|
||||||
|
defer prepareTestEnv(t)()
|
||||||
|
user := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User)
|
||||||
|
session := loginUser(t, user.Name)
|
||||||
|
token := getTokenForLoggedInUser(t, session)
|
||||||
|
repo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 1}).(*models.Repository)
|
||||||
|
|
||||||
|
req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/reviewers?token=%s", user.Name, repo.Name, token)
|
||||||
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||||
|
var reviewers []*api.User
|
||||||
|
DecodeJSON(t, resp, &reviewers)
|
||||||
|
assert.Len(t, reviewers, 4)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAPIRepoGetAssignees(t *testing.T) {
|
||||||
|
defer prepareTestEnv(t)()
|
||||||
|
user := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User)
|
||||||
|
session := loginUser(t, user.Name)
|
||||||
|
token := getTokenForLoggedInUser(t, session)
|
||||||
|
repo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 1}).(*models.Repository)
|
||||||
|
|
||||||
|
req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/assignees?token=%s", user.Name, repo.Name, token)
|
||||||
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||||
|
var assignees []*api.User
|
||||||
|
DecodeJSON(t, resp, &assignees)
|
||||||
|
assert.Len(t, assignees, 1)
|
||||||
|
}
|
||||||
|
|
|
@ -25,6 +25,15 @@ func ToUser(user, doer *models.User) *api.User {
|
||||||
return toUser(user, signed, authed)
|
return toUser(user, signed, authed)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ToUsers convert list of models.User to list of api.User
|
||||||
|
func ToUsers(doer *models.User, users []*models.User) []*api.User {
|
||||||
|
result := make([]*api.User, len(users))
|
||||||
|
for i := range users {
|
||||||
|
result[i] = ToUser(users[i], doer)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
// ToUserWithAccessMode convert models.User to api.User
|
// ToUserWithAccessMode convert models.User to api.User
|
||||||
// AccessMode is not none show add some more information
|
// AccessMode is not none show add some more information
|
||||||
func ToUserWithAccessMode(user *models.User, accessMode models.AccessMode) *api.User {
|
func ToUserWithAccessMode(user *models.User, accessMode models.AccessMode) *api.User {
|
||||||
|
|
|
@ -746,6 +746,8 @@ func Routes() *web.Route {
|
||||||
Put(reqAdmin(), bind(api.AddCollaboratorOption{}), repo.AddCollaborator).
|
Put(reqAdmin(), bind(api.AddCollaboratorOption{}), repo.AddCollaborator).
|
||||||
Delete(reqAdmin(), repo.DeleteCollaborator)
|
Delete(reqAdmin(), repo.DeleteCollaborator)
|
||||||
}, reqToken())
|
}, reqToken())
|
||||||
|
m.Get("/assignees", reqToken(), reqAnyRepoReader(), repo.GetAssignees)
|
||||||
|
m.Get("/reviewers", reqToken(), reqAnyRepoReader(), repo.GetReviewers)
|
||||||
m.Group("/teams", func() {
|
m.Group("/teams", func() {
|
||||||
m.Get("", reqAnyRepoReader(), repo.ListTeams)
|
m.Get("", reqAnyRepoReader(), repo.ListTeams)
|
||||||
m.Combo("/{team}").Get(reqAnyRepoReader(), repo.IsTeam).
|
m.Combo("/{team}").Get(reqAnyRepoReader(), repo.IsTeam).
|
||||||
|
|
|
@ -65,7 +65,7 @@ func ListRepoNotifications(ctx *context.APIContext) {
|
||||||
// - name: all
|
// - name: all
|
||||||
// in: query
|
// in: query
|
||||||
// description: If true, show notifications marked as read. Default value is false
|
// description: If true, show notifications marked as read. Default value is false
|
||||||
// type: string
|
// type: boolean
|
||||||
// - name: status-types
|
// - name: status-types
|
||||||
// in: query
|
// in: query
|
||||||
// description: "Show notifications with the provided status types. Options are: unread, read and/or pinned. Defaults to unread & pinned"
|
// description: "Show notifications with the provided status types. Options are: unread, read and/or pinned. Defaults to unread & pinned"
|
||||||
|
|
|
@ -27,7 +27,7 @@ func ListNotifications(ctx *context.APIContext) {
|
||||||
// - name: all
|
// - name: all
|
||||||
// in: query
|
// in: query
|
||||||
// description: If true, show notifications marked as read. Default value is false
|
// description: If true, show notifications marked as read. Default value is false
|
||||||
// type: string
|
// type: boolean
|
||||||
// - name: status-types
|
// - name: status-types
|
||||||
// in: query
|
// in: query
|
||||||
// description: "Show notifications with the provided status types. Options are: unread, read and/or pinned. Defaults to unread & pinned."
|
// description: "Show notifications with the provided status types. Options are: unread, read and/or pinned. Defaults to unread & pinned."
|
||||||
|
|
|
@ -221,3 +221,63 @@ func DeleteCollaborator(ctx *context.APIContext) {
|
||||||
}
|
}
|
||||||
ctx.Status(http.StatusNoContent)
|
ctx.Status(http.StatusNoContent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetReviewers return all users that can be requested to review in this repo
|
||||||
|
func GetReviewers(ctx *context.APIContext) {
|
||||||
|
// swagger:operation GET /repos/{owner}/{repo}/reviewers repository repoGetReviewers
|
||||||
|
// ---
|
||||||
|
// summary: Return all users that can be requested to review in this repo
|
||||||
|
// produces:
|
||||||
|
// - application/json
|
||||||
|
// parameters:
|
||||||
|
// - name: owner
|
||||||
|
// in: path
|
||||||
|
// description: owner of the repo
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// - name: repo
|
||||||
|
// in: path
|
||||||
|
// description: name of the repo
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// responses:
|
||||||
|
// "200":
|
||||||
|
// "$ref": "#/responses/UserList"
|
||||||
|
|
||||||
|
reviewers, err := ctx.Repo.Repository.GetReviewers(ctx.User.ID, 0)
|
||||||
|
if err != nil {
|
||||||
|
ctx.Error(http.StatusInternalServerError, "ListCollaborators", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.JSON(http.StatusOK, convert.ToUsers(ctx.User, reviewers))
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAssignees return all users that have write access and can be assigned to issues
|
||||||
|
func GetAssignees(ctx *context.APIContext) {
|
||||||
|
// swagger:operation GET /repos/{owner}/{repo}/assignees repository repoGetAssignees
|
||||||
|
// ---
|
||||||
|
// summary: Return all users that have write access and can be assigned to issues
|
||||||
|
// produces:
|
||||||
|
// - application/json
|
||||||
|
// parameters:
|
||||||
|
// - name: owner
|
||||||
|
// in: path
|
||||||
|
// description: owner of the repo
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// - name: repo
|
||||||
|
// in: path
|
||||||
|
// description: name of the repo
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// responses:
|
||||||
|
// "200":
|
||||||
|
// "$ref": "#/responses/UserList"
|
||||||
|
|
||||||
|
assignees, err := ctx.Repo.Repository.GetAssignees()
|
||||||
|
if err != nil {
|
||||||
|
ctx.Error(http.StatusInternalServerError, "ListCollaborators", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.JSON(http.StatusOK, convert.ToUsers(ctx.User, assignees))
|
||||||
|
}
|
||||||
|
|
|
@ -13,7 +13,6 @@ import (
|
||||||
"code.gitea.io/gitea/models"
|
"code.gitea.io/gitea/models"
|
||||||
"code.gitea.io/gitea/modules/context"
|
"code.gitea.io/gitea/modules/context"
|
||||||
"code.gitea.io/gitea/modules/convert"
|
"code.gitea.io/gitea/modules/convert"
|
||||||
api "code.gitea.io/gitea/modules/structs"
|
|
||||||
"code.gitea.io/gitea/routers/api/v1/utils"
|
"code.gitea.io/gitea/routers/api/v1/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -73,18 +72,13 @@ func Search(ctx *context.APIContext) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
results := make([]*api.User, len(users))
|
|
||||||
for i := range users {
|
|
||||||
results[i] = convert.ToUser(users[i], ctx.User)
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.SetLinkHeader(int(maxResults), listOptions.PageSize)
|
ctx.SetLinkHeader(int(maxResults), listOptions.PageSize)
|
||||||
ctx.Header().Set("X-Total-Count", fmt.Sprintf("%d", maxResults))
|
ctx.Header().Set("X-Total-Count", fmt.Sprintf("%d", maxResults))
|
||||||
ctx.Header().Set("Access-Control-Expose-Headers", "X-Total-Count, Link")
|
ctx.Header().Set("Access-Control-Expose-Headers", "X-Total-Count, Link")
|
||||||
|
|
||||||
ctx.JSON(http.StatusOK, map[string]interface{}{
|
ctx.JSON(http.StatusOK, map[string]interface{}{
|
||||||
"ok": true,
|
"ok": true,
|
||||||
"data": results,
|
"data": convert.ToUsers(ctx.User, users),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -630,7 +630,7 @@
|
||||||
"operationId": "notifyGetList",
|
"operationId": "notifyGetList",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "boolean",
|
||||||
"description": "If true, show notifications marked as read. Default value is false",
|
"description": "If true, show notifications marked as read. Default value is false",
|
||||||
"name": "all",
|
"name": "all",
|
||||||
"in": "query"
|
"in": "query"
|
||||||
|
@ -2277,6 +2277,39 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/repos/{owner}/{repo}/assignees": {
|
||||||
|
"get": {
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"repository"
|
||||||
|
],
|
||||||
|
"summary": "Return all users that have write access and can be assigned to issues",
|
||||||
|
"operationId": "repoGetAssignees",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "owner of the repo",
|
||||||
|
"name": "owner",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "name of the repo",
|
||||||
|
"name": "repo",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"$ref": "#/responses/UserList"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/repos/{owner}/{repo}/branch_protections": {
|
"/repos/{owner}/{repo}/branch_protections": {
|
||||||
"get": {
|
"get": {
|
||||||
"produces": [
|
"produces": [
|
||||||
|
@ -6844,7 +6877,7 @@
|
||||||
"required": true
|
"required": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "boolean",
|
||||||
"description": "If true, show notifications marked as read. Default value is false",
|
"description": "If true, show notifications marked as read. Default value is false",
|
||||||
"name": "all",
|
"name": "all",
|
||||||
"in": "query"
|
"in": "query"
|
||||||
|
@ -8629,6 +8662,39 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/repos/{owner}/{repo}/reviewers": {
|
||||||
|
"get": {
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"repository"
|
||||||
|
],
|
||||||
|
"summary": "Return all users that can be requested to review in this repo",
|
||||||
|
"operationId": "repoGetReviewers",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "owner of the repo",
|
||||||
|
"name": "owner",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "name of the repo",
|
||||||
|
"name": "repo",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"$ref": "#/responses/UserList"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/repos/{owner}/{repo}/signing-key.gpg": {
|
"/repos/{owner}/{repo}/signing-key.gpg": {
|
||||||
"get": {
|
"get": {
|
||||||
"produces": [
|
"produces": [
|
||||||
|
|
Loading…
Reference in New Issue