[API] Milestone endpoints accept names too (#12649)

* API: Milestone endpoints accept names too

* add test

* rename

Co-authored-by: Lauris BH <lauris@nix.lv>
release/v1.15
6543 2020-09-14 13:48:03 +02:00 committed by GitHub
parent 33f606ce4c
commit 00a806de68
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 60 additions and 36 deletions

View File

@ -61,6 +61,11 @@ func TestAPIIssuesMilestone(t *testing.T) {
DecodeJSON(t, resp, &apiMilestones) DecodeJSON(t, resp, &apiMilestones)
assert.Len(t, apiMilestones, 4) assert.Len(t, apiMilestones, 4)
req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/milestones/%s?token=%s", owner.Name, repo.Name, apiMilestones[2].Title, token))
resp = session.MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &apiMilestone)
assert.EqualValues(t, apiMilestones[2], apiMilestone)
req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/milestones?state=%s&name=%s&token=%s", owner.Name, repo.Name, "all", "milestone2", token)) req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/milestones?state=%s&name=%s&token=%s", owner.Name, repo.Name, "all", "milestone2", token))
resp = session.MakeRequest(t, req, http.StatusOK) resp = session.MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &apiMilestones) DecodeJSON(t, resp, &apiMilestones)

View File

@ -7,6 +7,7 @@ package repo
import ( import (
"net/http" "net/http"
"strconv"
"time" "time"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
@ -73,7 +74,7 @@ func ListMilestones(ctx *context.APIContext) {
ctx.JSON(http.StatusOK, &apiMilestones) ctx.JSON(http.StatusOK, &apiMilestones)
} }
// GetMilestone get a milestone for a repository // GetMilestone get a milestone for a repository by ID and if not available by name
func GetMilestone(ctx *context.APIContext) { func GetMilestone(ctx *context.APIContext) {
// swagger:operation GET /repos/{owner}/{repo}/milestones/{id} issue issueGetMilestone // swagger:operation GET /repos/{owner}/{repo}/milestones/{id} issue issueGetMilestone
// --- // ---
@ -93,23 +94,18 @@ func GetMilestone(ctx *context.APIContext) {
// required: true // required: true
// - name: id // - name: id
// in: path // in: path
// description: id of the milestone // description: the milestone to get, identified by ID and if not available by name
// type: integer // type: string
// format: int64
// required: true // required: true
// responses: // responses:
// "200": // "200":
// "$ref": "#/responses/Milestone" // "$ref": "#/responses/Milestone"
milestone, err := models.GetMilestoneByRepoID(ctx.Repo.Repository.ID, ctx.ParamsInt64(":id")) milestone := getMilestoneByIDOrName(ctx)
if err != nil { if ctx.Written() {
if models.IsErrMilestoneNotExist(err) {
ctx.NotFound()
} else {
ctx.Error(http.StatusInternalServerError, "GetMilestoneByRepoID", err)
}
return return
} }
ctx.JSON(http.StatusOK, convert.ToAPIMilestone(milestone)) ctx.JSON(http.StatusOK, convert.ToAPIMilestone(milestone))
} }
@ -165,7 +161,7 @@ func CreateMilestone(ctx *context.APIContext, form api.CreateMilestoneOption) {
ctx.JSON(http.StatusCreated, convert.ToAPIMilestone(milestone)) ctx.JSON(http.StatusCreated, convert.ToAPIMilestone(milestone))
} }
// EditMilestone modify a milestone for a repository // EditMilestone modify a milestone for a repository by ID and if not available by name
func EditMilestone(ctx *context.APIContext, form api.EditMilestoneOption) { func EditMilestone(ctx *context.APIContext, form api.EditMilestoneOption) {
// swagger:operation PATCH /repos/{owner}/{repo}/milestones/{id} issue issueEditMilestone // swagger:operation PATCH /repos/{owner}/{repo}/milestones/{id} issue issueEditMilestone
// --- // ---
@ -187,9 +183,8 @@ func EditMilestone(ctx *context.APIContext, form api.EditMilestoneOption) {
// required: true // required: true
// - name: id // - name: id
// in: path // in: path
// description: id of the milestone // description: the milestone to edit, identified by ID and if not available by name
// type: integer // type: string
// format: int64
// required: true // required: true
// - name: body // - name: body
// in: body // in: body
@ -199,13 +194,8 @@ func EditMilestone(ctx *context.APIContext, form api.EditMilestoneOption) {
// "200": // "200":
// "$ref": "#/responses/Milestone" // "$ref": "#/responses/Milestone"
milestone, err := models.GetMilestoneByRepoID(ctx.Repo.Repository.ID, ctx.ParamsInt64(":id")) milestone := getMilestoneByIDOrName(ctx)
if err != nil { if ctx.Written() {
if models.IsErrMilestoneNotExist(err) {
ctx.NotFound()
} else {
ctx.Error(http.StatusInternalServerError, "GetMilestoneByRepoID", err)
}
return return
} }
@ -231,7 +221,7 @@ func EditMilestone(ctx *context.APIContext, form api.EditMilestoneOption) {
ctx.JSON(http.StatusOK, convert.ToAPIMilestone(milestone)) ctx.JSON(http.StatusOK, convert.ToAPIMilestone(milestone))
} }
// DeleteMilestone delete a milestone for a repository // DeleteMilestone delete a milestone for a repository by ID and if not available by name
func DeleteMilestone(ctx *context.APIContext) { func DeleteMilestone(ctx *context.APIContext) {
// swagger:operation DELETE /repos/{owner}/{repo}/milestones/{id} issue issueDeleteMilestone // swagger:operation DELETE /repos/{owner}/{repo}/milestones/{id} issue issueDeleteMilestone
// --- // ---
@ -249,17 +239,49 @@ func DeleteMilestone(ctx *context.APIContext) {
// required: true // required: true
// - name: id // - name: id
// in: path // in: path
// description: id of the milestone to delete // description: the milestone to delete, identified by ID and if not available by name
// type: integer // type: string
// format: int64
// required: true // required: true
// responses: // responses:
// "204": // "204":
// "$ref": "#/responses/empty" // "$ref": "#/responses/empty"
if err := models.DeleteMilestoneByRepoID(ctx.Repo.Repository.ID, ctx.ParamsInt64(":id")); err != nil { m := getMilestoneByIDOrName(ctx)
if ctx.Written() {
return
}
if err := models.DeleteMilestoneByRepoID(ctx.Repo.Repository.ID, m.ID); err != nil {
ctx.Error(http.StatusInternalServerError, "DeleteMilestoneByRepoID", err) ctx.Error(http.StatusInternalServerError, "DeleteMilestoneByRepoID", err)
return return
} }
ctx.Status(http.StatusNoContent) ctx.Status(http.StatusNoContent)
} }
// getMilestoneByIDOrName get milestone by ID and if not available by name
func getMilestoneByIDOrName(ctx *context.APIContext) *models.Milestone {
mile := ctx.Params(":id")
mileID, _ := strconv.ParseInt(mile, 0, 64)
if mileID != 0 {
milestone, err := models.GetMilestoneByRepoID(ctx.Repo.Repository.ID, mileID)
if err == nil {
return milestone
} else if !models.IsErrMilestoneNotExist(err) {
ctx.Error(http.StatusInternalServerError, "GetMilestoneByRepoID", err)
return nil
}
}
milestone, err := models.GetMilestoneByRepoIDANDName(ctx.Repo.Repository.ID, mile)
if err != nil {
if models.IsErrMilestoneNotExist(err) {
ctx.NotFound()
return nil
}
ctx.Error(http.StatusInternalServerError, "GetMilestoneByRepoID", err)
return nil
}
return milestone
}

View File

@ -6353,9 +6353,8 @@
"required": true "required": true
}, },
{ {
"type": "integer", "type": "string",
"format": "int64", "description": "the milestone to get, identified by ID and if not available by name",
"description": "id of the milestone",
"name": "id", "name": "id",
"in": "path", "in": "path",
"required": true "required": true
@ -6389,9 +6388,8 @@
"required": true "required": true
}, },
{ {
"type": "integer", "type": "string",
"format": "int64", "description": "the milestone to delete, identified by ID and if not available by name",
"description": "id of the milestone to delete",
"name": "id", "name": "id",
"in": "path", "in": "path",
"required": true "required": true
@ -6431,9 +6429,8 @@
"required": true "required": true
}, },
{ {
"type": "integer", "type": "string",
"format": "int64", "description": "the milestone to edit, identified by ID and if not available by name",
"description": "id of the milestone",
"name": "id", "name": "id",
"in": "path", "in": "path",
"required": true "required": true