[GITEA] DELETE /repos/{owner}/{repo}/pulls/{index}/reviews/{id}/comments/{comment}
* reuse deleteIssueComment by adding the commentType parameter
* ensure tests start with a PR with no random reviews from fixtures
Refs: https://codeberg.org/forgejo/forgejo/issues/2109
(cherry picked from commit 5b90ab77f6
)
This commit is contained in:
parent
c67255192e
commit
28ecd6f5a6
5 changed files with 156 additions and 6 deletions
|
@ -1265,7 +1265,11 @@ func Routes() *web.Route {
|
||||||
m.Combo("").
|
m.Combo("").
|
||||||
Get(repo.GetPullReviewComments).
|
Get(repo.GetPullReviewComments).
|
||||||
Post(reqToken(), bind(api.CreatePullReviewCommentOptions{}), repo.CreatePullReviewComment)
|
Post(reqToken(), bind(api.CreatePullReviewCommentOptions{}), repo.CreatePullReviewComment)
|
||||||
m.Get("/{comment}", commentAssignment("comment"), repo.GetPullReviewComment)
|
m.Group("/{comment}", func() {
|
||||||
|
m.Combo("").
|
||||||
|
Get(repo.GetPullReviewComment).
|
||||||
|
Delete(reqToken(), repo.DeletePullReviewComment)
|
||||||
|
}, commentAssignment("comment"))
|
||||||
})
|
})
|
||||||
m.Post("/dismissals", reqToken(), bind(api.DismissPullReviewOptions{}), repo.DismissPullReview)
|
m.Post("/dismissals", reqToken(), bind(api.DismissPullReviewOptions{}), repo.DismissPullReview)
|
||||||
m.Post("/undismissals", reqToken(), repo.UnDismissPullReview)
|
m.Post("/undismissals", reqToken(), repo.UnDismissPullReview)
|
||||||
|
|
|
@ -624,7 +624,7 @@ func DeleteIssueComment(ctx *context.APIContext) {
|
||||||
// "404":
|
// "404":
|
||||||
// "$ref": "#/responses/notFound"
|
// "$ref": "#/responses/notFound"
|
||||||
|
|
||||||
deleteIssueComment(ctx)
|
deleteIssueComment(ctx, issues_model.CommentTypeComment)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteIssueCommentDeprecated delete a comment from an issue
|
// DeleteIssueCommentDeprecated delete a comment from an issue
|
||||||
|
@ -663,16 +663,16 @@ func DeleteIssueCommentDeprecated(ctx *context.APIContext) {
|
||||||
// "404":
|
// "404":
|
||||||
// "$ref": "#/responses/notFound"
|
// "$ref": "#/responses/notFound"
|
||||||
|
|
||||||
deleteIssueComment(ctx)
|
deleteIssueComment(ctx, issues_model.CommentTypeComment)
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteIssueComment(ctx *context.APIContext) {
|
func deleteIssueComment(ctx *context.APIContext, commentType issues_model.CommentType) {
|
||||||
comment := ctx.Comment
|
comment := ctx.Comment
|
||||||
|
|
||||||
if !ctx.IsSigned || (ctx.Doer.ID != comment.PosterID && !ctx.Repo.CanWriteIssuesOrPulls(comment.Issue.IsPull)) {
|
if !ctx.IsSigned || (ctx.Doer.ID != comment.PosterID && !ctx.Repo.CanWriteIssuesOrPulls(comment.Issue.IsPull)) {
|
||||||
ctx.Status(http.StatusForbidden)
|
ctx.Status(http.StatusForbidden)
|
||||||
return
|
return
|
||||||
} else if comment.Type != issues_model.CommentTypeComment {
|
} else if comment.Type != commentType {
|
||||||
ctx.Status(http.StatusNoContent)
|
ctx.Status(http.StatusNoContent)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -1015,6 +1015,53 @@ func UnDismissPullReview(ctx *context.APIContext) {
|
||||||
dismissReview(ctx, "", false, false)
|
dismissReview(ctx, "", false, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeletePullReviewComment delete a pull review comment
|
||||||
|
func DeletePullReviewComment(ctx *context.APIContext) {
|
||||||
|
// swagger:operation DELETE /repos/{owner}/{repo}/pulls/{index}/reviews/{id}/comments/{comment} repository repoDeletePullReviewComment
|
||||||
|
// ---
|
||||||
|
// summary: Delete a pull review comment
|
||||||
|
// 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
|
||||||
|
// - name: index
|
||||||
|
// in: path
|
||||||
|
// description: index of the pull request
|
||||||
|
// type: integer
|
||||||
|
// format: int64
|
||||||
|
// required: true
|
||||||
|
// - name: id
|
||||||
|
// in: path
|
||||||
|
// description: id of the review
|
||||||
|
// type: integer
|
||||||
|
// format: int64
|
||||||
|
// required: true
|
||||||
|
// - name: comment
|
||||||
|
// in: path
|
||||||
|
// description: id of the comment
|
||||||
|
// type: integer
|
||||||
|
// format: int64
|
||||||
|
// required: true
|
||||||
|
// responses:
|
||||||
|
// "204":
|
||||||
|
// "$ref": "#/responses/empty"
|
||||||
|
// "403":
|
||||||
|
// "$ref": "#/responses/forbidden"
|
||||||
|
// "404":
|
||||||
|
// "$ref": "#/responses/notFound"
|
||||||
|
|
||||||
|
deleteIssueComment(ctx, issues_model.CommentTypeCode)
|
||||||
|
}
|
||||||
|
|
||||||
func dismissReview(ctx *context.APIContext, msg string, isDismiss, dismissPriors bool) {
|
func dismissReview(ctx *context.APIContext, msg string, isDismiss, dismissPriors bool) {
|
||||||
if !ctx.Repo.IsAdmin() {
|
if !ctx.Repo.IsAdmin() {
|
||||||
ctx.Error(http.StatusForbidden, "", "Must be repo admin")
|
ctx.Error(http.StatusForbidden, "", "Must be repo admin")
|
||||||
|
|
61
templates/swagger/v1_json.tmpl
generated
61
templates/swagger/v1_json.tmpl
generated
|
@ -11666,6 +11666,67 @@
|
||||||
"$ref": "#/responses/notFound"
|
"$ref": "#/responses/notFound"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"delete": {
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"repository"
|
||||||
|
],
|
||||||
|
"summary": "Delete a pull review comment",
|
||||||
|
"operationId": "repoDeletePullReviewComment",
|
||||||
|
"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
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int64",
|
||||||
|
"description": "index of the pull request",
|
||||||
|
"name": "index",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int64",
|
||||||
|
"description": "id of the review",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int64",
|
||||||
|
"description": "id of the comment",
|
||||||
|
"name": "comment",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"204": {
|
||||||
|
"$ref": "#/responses/empty"
|
||||||
|
},
|
||||||
|
"403": {
|
||||||
|
"$ref": "#/responses/forbidden"
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"$ref": "#/responses/notFound"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/repos/{owner}/{repo}/pulls/{index}/reviews/{id}/dismissals": {
|
"/repos/{owner}/{repo}/pulls/{index}/reviews/{id}/dismissals": {
|
||||||
|
|
|
@ -21,7 +21,7 @@ import (
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestAPIPullReviewCreateComment(t *testing.T) {
|
func TestAPIPullReviewCreateDeleteComment(t *testing.T) {
|
||||||
defer tests.PrepareTestEnv(t)()
|
defer tests.PrepareTestEnv(t)()
|
||||||
pullIssue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 3})
|
pullIssue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 3})
|
||||||
assert.NoError(t, pullIssue.LoadAttributes(db.DefaultContext))
|
assert.NoError(t, pullIssue.LoadAttributes(db.DefaultContext))
|
||||||
|
@ -47,6 +47,30 @@ func TestAPIPullReviewCreateComment(t *testing.T) {
|
||||||
var review api.PullReview
|
var review api.PullReview
|
||||||
var reviewLine int64 = 1
|
var reviewLine int64 = 1
|
||||||
|
|
||||||
|
// cleanup
|
||||||
|
{
|
||||||
|
session := loginUser(t, "user1")
|
||||||
|
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeAll)
|
||||||
|
|
||||||
|
req := NewRequestf(t, http.MethodGet, "/api/v1/repos/%s/pulls/%d/reviews", repo.FullName(), pullIssue.Index).AddTokenAuth(token)
|
||||||
|
resp := MakeRequest(t, req, http.StatusOK)
|
||||||
|
var reviews []*api.PullReview
|
||||||
|
DecodeJSON(t, resp, &reviews)
|
||||||
|
for _, review := range reviews {
|
||||||
|
req := NewRequestf(t, http.MethodDelete, "/api/v1/repos/%s/pulls/%d/reviews/%d", repo.FullName(), pullIssue.Index, review.ID).
|
||||||
|
AddTokenAuth(token)
|
||||||
|
MakeRequest(t, req, http.StatusNoContent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
requireReviewCount := func(count int) {
|
||||||
|
req := NewRequestf(t, http.MethodGet, "/api/v1/repos/%s/pulls/%d/reviews", repo.FullName(), pullIssue.Index).AddTokenAuth(token)
|
||||||
|
resp := MakeRequest(t, req, http.StatusOK)
|
||||||
|
var reviews []*api.PullReview
|
||||||
|
DecodeJSON(t, resp, &reviews)
|
||||||
|
require.EqualValues(t, count, len(reviews))
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
req := NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/pulls/%d/reviews", repo.FullName(), pullIssue.Index), &api.CreatePullReviewOptions{
|
req := NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/pulls/%d/reviews", repo.FullName(), pullIssue.Index), &api.CreatePullReviewOptions{
|
||||||
Body: "body1",
|
Body: "body1",
|
||||||
|
@ -66,6 +90,7 @@ func TestAPIPullReviewCreateComment(t *testing.T) {
|
||||||
DecodeJSON(t, resp, &getReview)
|
DecodeJSON(t, resp, &getReview)
|
||||||
require.EqualValues(t, getReview, review)
|
require.EqualValues(t, getReview, review)
|
||||||
}
|
}
|
||||||
|
requireReviewCount(1)
|
||||||
|
|
||||||
newCommentBody := "first new line"
|
newCommentBody := "first new line"
|
||||||
var reviewComment api.PullReviewComment
|
var reviewComment api.PullReviewComment
|
||||||
|
@ -95,11 +120,24 @@ func TestAPIPullReviewCreateComment(t *testing.T) {
|
||||||
assert.EqualValues(t, reviewComment, comment)
|
assert.EqualValues(t, reviewComment, comment)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
req := NewRequestf(t, http.MethodDelete, "/api/v1/repos/%s/pulls/%d/reviews/%d/comments/%d", repo.FullName(), pullIssue.Index, review.ID, reviewComment.ID).
|
||||||
|
AddTokenAuth(token)
|
||||||
|
MakeRequest(t, req, http.StatusNoContent)
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
req := NewRequestf(t, http.MethodGet, "/api/v1/repos/%s/pulls/%d/reviews/%d/comments/%d", repo.FullName(), pullIssue.Index, review.ID, reviewComment.ID).
|
||||||
|
AddTokenAuth(token)
|
||||||
|
MakeRequest(t, req, http.StatusNotFound)
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
req := NewRequestf(t, http.MethodDelete, "/api/v1/repos/%s/pulls/%d/reviews/%d", repo.FullName(), pullIssue.Index, review.ID).
|
req := NewRequestf(t, http.MethodDelete, "/api/v1/repos/%s/pulls/%d/reviews/%d", repo.FullName(), pullIssue.Index, review.ID).
|
||||||
AddTokenAuth(token)
|
AddTokenAuth(token)
|
||||||
MakeRequest(t, req, http.StatusNoContent)
|
MakeRequest(t, req, http.StatusNoContent)
|
||||||
}
|
}
|
||||||
|
requireReviewCount(0)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue