From e88d67b774ae615208b25133c299f2d50b3a018b Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Wed, 8 Jan 2020 08:00:59 +0100 Subject: [PATCH] [API] add comments endpoint for single comment (#9494) * add GET /repos/{owner}/{repo}/issues/comments/{id} and complete error list for swagger in other func * add repo check --- integrations/api_comment_test.go | 27 ++++++++++ routers/api/v1/api.go | 7 +-- routers/api/v1/repo/issue_comment.go | 81 ++++++++++++++++++++++++++++ templates/swagger/v1_json.tmpl | 69 ++++++++++++++++++++++++ 4 files changed, 181 insertions(+), 3 deletions(-) diff --git a/integrations/api_comment_test.go b/integrations/api_comment_test.go index 0716c5d859..d21f56aaf8 100644 --- a/integrations/api_comment_test.go +++ b/integrations/api_comment_test.go @@ -83,6 +83,33 @@ func TestAPICreateComment(t *testing.T) { models.AssertExistsAndLoadBean(t, &models.Comment{ID: updatedComment.ID, IssueID: issue.ID, Content: commentBody}) } +func TestAPIGetComment(t *testing.T) { + defer prepareTestEnv(t)() + + comment := models.AssertExistsAndLoadBean(t, &models.Comment{ID: 2}).(*models.Comment) + assert.NoError(t, comment.LoadIssue()) + repo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: comment.Issue.RepoID}).(*models.Repository) + repoOwner := models.AssertExistsAndLoadBean(t, &models.User{ID: repo.OwnerID}).(*models.User) + + session := loginUser(t, repoOwner.Name) + token := getTokenForLoggedInUser(t, session) + req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues/comments/%d", repoOwner.Name, repo.Name, comment.ID) + resp := session.MakeRequest(t, req, http.StatusOK) + req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues/comments/%d?token=%s", repoOwner.Name, repo.Name, comment.ID, token) + resp = session.MakeRequest(t, req, http.StatusOK) + + var apiComment api.Comment + DecodeJSON(t, resp, &apiComment) + + assert.NoError(t, comment.LoadPoster()) + expect := comment.APIFormat() + + assert.Equal(t, expect.ID, apiComment.ID) + assert.Equal(t, expect.Poster.FullName, apiComment.Poster.FullName) + assert.Equal(t, expect.Body, apiComment.Body) + assert.Equal(t, expect.Created.Unix(), apiComment.Created.Unix()) +} + func TestAPIEditComment(t *testing.T) { defer prepareTestEnv(t)() const newCommentBody = "This is the new comment body" diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index e4288f40f6..3f766c7a74 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -661,9 +661,10 @@ func RegisterRoutes(m *macaron.Macaron) { m.Group("/comments", func() { m.Get("", repo.ListRepoIssueComments) m.Group("/:id", func() { - m.Combo("", reqToken()). - Patch(mustNotBeArchived, bind(api.EditIssueCommentOption{}), repo.EditIssueComment). - Delete(repo.DeleteIssueComment) + m.Combo(""). + Get(repo.GetIssueComment). + Patch(mustNotBeArchived, reqToken(), bind(api.EditIssueCommentOption{}), repo.EditIssueComment). + Delete(reqToken(), repo.DeleteIssueComment) m.Combo("/reactions"). Get(repo.GetIssueCommentReactions). Post(bind(api.EditReactionOption{}), reqToken(), repo.PostIssueCommentReaction). diff --git a/routers/api/v1/repo/issue_comment.go b/routers/api/v1/repo/issue_comment.go index c13fc93cdf..3085c2e51f 100644 --- a/routers/api/v1/repo/issue_comment.go +++ b/routers/api/v1/repo/issue_comment.go @@ -204,6 +204,74 @@ func CreateIssueComment(ctx *context.APIContext, form api.CreateIssueCommentOpti ctx.JSON(http.StatusCreated, comment.APIFormat()) } +// GetIssueComment Get a comment by ID +func GetIssueComment(ctx *context.APIContext) { + // swagger:operation GET /repos/{owner}/{repo}/issues/comments/{id} issue issueGetComment + // --- + // summary: Get a comment + // consumes: + // - application/json + // 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: id + // in: path + // description: id of the comment + // type: integer + // format: int64 + // required: true + // responses: + // "200": + // "$ref": "#/responses/Comment" + // "204": + // "$ref": "#/responses/empty" + // "403": + // "$ref": "#/responses/forbidden" + // "404": + // "$ref": "#/responses/notFound" + + comment, err := models.GetCommentByID(ctx.ParamsInt64(":id")) + if err != nil { + if models.IsErrCommentNotExist(err) { + ctx.NotFound(err) + } else { + ctx.Error(http.StatusInternalServerError, "GetCommentByID", err) + } + return + } + + if err = comment.LoadIssue(); err != nil { + ctx.InternalServerError(err) + return + } + if comment.Issue.RepoID != ctx.Repo.Repository.ID { + ctx.Status(http.StatusNotFound) + return + } + + if comment.Type != models.CommentTypeComment { + ctx.Status(http.StatusNoContent) + return + } + + if err := comment.LoadPoster(); err != nil { + ctx.Error(http.StatusInternalServerError, "comment.LoadPoster", err) + return + } + + ctx.JSON(http.StatusOK, comment.APIFormat()) +} + // EditIssueComment modify a comment of an issue func EditIssueComment(ctx *context.APIContext, form api.EditIssueCommentOption) { // swagger:operation PATCH /repos/{owner}/{repo}/issues/comments/{id} issue issueEditComment @@ -237,6 +305,13 @@ func EditIssueComment(ctx *context.APIContext, form api.EditIssueCommentOption) // responses: // "200": // "$ref": "#/responses/Comment" + // "204": + // "$ref": "#/responses/empty" + // "403": + // "$ref": "#/responses/forbidden" + // "404": + // "$ref": "#/responses/notFound" + editIssueComment(ctx, form) } @@ -283,6 +358,8 @@ func EditIssueCommentDeprecated(ctx *context.APIContext, form api.EditIssueComme // "$ref": "#/responses/empty" // "403": // "$ref": "#/responses/forbidden" + // "404": + // "$ref": "#/responses/notFound" editIssueComment(ctx, form) } @@ -343,6 +420,8 @@ func DeleteIssueComment(ctx *context.APIContext) { // "$ref": "#/responses/empty" // "403": // "$ref": "#/responses/forbidden" + // "404": + // "$ref": "#/responses/notFound" deleteIssueComment(ctx) } @@ -380,6 +459,8 @@ func DeleteIssueCommentDeprecated(ctx *context.APIContext) { // "$ref": "#/responses/empty" // "403": // "$ref": "#/responses/forbidden" + // "404": + // "$ref": "#/responses/notFound" deleteIssueComment(ctx) } diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 45e84d3ed0..f37c900cca 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -3002,6 +3002,57 @@ } }, "/repos/{owner}/{repo}/issues/comments/{id}": { + "get": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "issue" + ], + "summary": "Get a comment", + "operationId": "issueGetComment", + "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": "id of the comment", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/Comment" + }, + "204": { + "$ref": "#/responses/empty" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, "delete": { "tags": [ "issue" @@ -3038,6 +3089,9 @@ }, "403": { "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" } } }, @@ -3087,6 +3141,15 @@ "responses": { "200": { "$ref": "#/responses/Comment" + }, + "204": { + "$ref": "#/responses/empty" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" } } } @@ -3491,6 +3554,9 @@ }, "403": { "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" } } }, @@ -3554,6 +3620,9 @@ }, "403": { "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" } } }