code.gitea.io/gitea@v1.21.7/tests/integration/api_comment_test.go (about) 1 // Copyright 2017 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package integration 5 6 import ( 7 "fmt" 8 "net/http" 9 "net/url" 10 "testing" 11 12 auth_model "code.gitea.io/gitea/models/auth" 13 "code.gitea.io/gitea/models/db" 14 issues_model "code.gitea.io/gitea/models/issues" 15 repo_model "code.gitea.io/gitea/models/repo" 16 "code.gitea.io/gitea/models/unittest" 17 user_model "code.gitea.io/gitea/models/user" 18 api "code.gitea.io/gitea/modules/structs" 19 "code.gitea.io/gitea/services/convert" 20 "code.gitea.io/gitea/tests" 21 22 "github.com/stretchr/testify/assert" 23 ) 24 25 func TestAPIListRepoComments(t *testing.T) { 26 defer tests.PrepareTestEnv(t)() 27 28 comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{}, 29 unittest.Cond("type = ?", issues_model.CommentTypeComment)) 30 issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: comment.IssueID}) 31 repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}) 32 repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) 33 34 link, _ := url.Parse(fmt.Sprintf("/api/v1/repos/%s/%s/issues/comments", repoOwner.Name, repo.Name)) 35 req := NewRequest(t, "GET", link.String()) 36 resp := MakeRequest(t, req, http.StatusOK) 37 38 var apiComments []*api.Comment 39 DecodeJSON(t, resp, &apiComments) 40 assert.Len(t, apiComments, 2) 41 for _, apiComment := range apiComments { 42 c := &issues_model.Comment{ID: apiComment.ID} 43 unittest.AssertExistsAndLoadBean(t, c, 44 unittest.Cond("type = ?", issues_model.CommentTypeComment)) 45 unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: c.IssueID, RepoID: repo.ID}) 46 } 47 48 // test before and since filters 49 query := url.Values{} 50 before := "2000-01-01T00:00:11+00:00" // unix: 946684811 51 since := "2000-01-01T00:00:12+00:00" // unix: 946684812 52 query.Add("before", before) 53 link.RawQuery = query.Encode() 54 req = NewRequest(t, "GET", link.String()) 55 resp = MakeRequest(t, req, http.StatusOK) 56 DecodeJSON(t, resp, &apiComments) 57 assert.Len(t, apiComments, 1) 58 assert.EqualValues(t, 2, apiComments[0].ID) 59 60 query.Del("before") 61 query.Add("since", since) 62 link.RawQuery = query.Encode() 63 req = NewRequest(t, "GET", link.String()) 64 resp = MakeRequest(t, req, http.StatusOK) 65 DecodeJSON(t, resp, &apiComments) 66 assert.Len(t, apiComments, 1) 67 assert.EqualValues(t, 3, apiComments[0].ID) 68 } 69 70 func TestAPIListIssueComments(t *testing.T) { 71 defer tests.PrepareTestEnv(t)() 72 73 comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{}, 74 unittest.Cond("type = ?", issues_model.CommentTypeComment)) 75 issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: comment.IssueID}) 76 repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}) 77 repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) 78 79 token := getUserToken(t, repoOwner.Name, auth_model.AccessTokenScopeReadIssue) 80 req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues/%d/comments?token=%s", 81 repoOwner.Name, repo.Name, issue.Index, token) 82 resp := MakeRequest(t, req, http.StatusOK) 83 84 var comments []*api.Comment 85 DecodeJSON(t, resp, &comments) 86 expectedCount := unittest.GetCount(t, &issues_model.Comment{IssueID: issue.ID}, 87 unittest.Cond("type = ?", issues_model.CommentTypeComment)) 88 assert.Len(t, comments, expectedCount) 89 } 90 91 func TestAPICreateComment(t *testing.T) { 92 defer tests.PrepareTestEnv(t)() 93 const commentBody = "Comment body" 94 95 issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{}) 96 repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}) 97 repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) 98 99 token := getUserToken(t, repoOwner.Name, auth_model.AccessTokenScopeWriteIssue) 100 urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/comments?token=%s", 101 repoOwner.Name, repo.Name, issue.Index, token) 102 req := NewRequestWithValues(t, "POST", urlStr, map[string]string{ 103 "body": commentBody, 104 }) 105 resp := MakeRequest(t, req, http.StatusCreated) 106 107 var updatedComment api.Comment 108 DecodeJSON(t, resp, &updatedComment) 109 assert.EqualValues(t, commentBody, updatedComment.Body) 110 unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: updatedComment.ID, IssueID: issue.ID, Content: commentBody}) 111 } 112 113 func TestAPIGetComment(t *testing.T) { 114 defer tests.PrepareTestEnv(t)() 115 116 comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 2}) 117 assert.NoError(t, comment.LoadIssue(db.DefaultContext)) 118 repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: comment.Issue.RepoID}) 119 repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) 120 121 token := getUserToken(t, repoOwner.Name, auth_model.AccessTokenScopeReadIssue) 122 req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues/comments/%d", repoOwner.Name, repo.Name, comment.ID) 123 MakeRequest(t, req, http.StatusOK) 124 req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues/comments/%d?token=%s", repoOwner.Name, repo.Name, comment.ID, token) 125 resp := MakeRequest(t, req, http.StatusOK) 126 127 var apiComment api.Comment 128 DecodeJSON(t, resp, &apiComment) 129 130 assert.NoError(t, comment.LoadPoster(db.DefaultContext)) 131 expect := convert.ToAPIComment(db.DefaultContext, repo, comment) 132 133 assert.Equal(t, expect.ID, apiComment.ID) 134 assert.Equal(t, expect.Poster.FullName, apiComment.Poster.FullName) 135 assert.Equal(t, expect.Body, apiComment.Body) 136 assert.Equal(t, expect.Created.Unix(), apiComment.Created.Unix()) 137 } 138 139 func TestAPIGetSystemUserComment(t *testing.T) { 140 defer tests.PrepareTestEnv(t)() 141 142 issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{}) 143 repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}) 144 repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) 145 146 for _, systemUser := range []*user_model.User{ 147 user_model.NewGhostUser(), 148 user_model.NewActionsUser(), 149 } { 150 body := fmt.Sprintf("Hello %s", systemUser.Name) 151 comment, err := issues_model.CreateComment(db.DefaultContext, &issues_model.CreateCommentOptions{ 152 Type: issues_model.CommentTypeComment, 153 Doer: systemUser, 154 Repo: repo, 155 Issue: issue, 156 Content: body, 157 }) 158 assert.NoError(t, err) 159 160 req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues/comments/%d", repoOwner.Name, repo.Name, comment.ID) 161 resp := MakeRequest(t, req, http.StatusOK) 162 163 var apiComment api.Comment 164 DecodeJSON(t, resp, &apiComment) 165 166 if assert.NotNil(t, apiComment.Poster) { 167 if assert.Equal(t, systemUser.ID, apiComment.Poster.ID) { 168 assert.NoError(t, comment.LoadPoster(db.DefaultContext)) 169 assert.Equal(t, systemUser.Name, apiComment.Poster.UserName) 170 } 171 } 172 assert.Equal(t, body, apiComment.Body) 173 } 174 } 175 176 func TestAPIEditComment(t *testing.T) { 177 defer tests.PrepareTestEnv(t)() 178 const newCommentBody = "This is the new comment body" 179 180 comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 8}, 181 unittest.Cond("type = ?", issues_model.CommentTypeComment)) 182 issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: comment.IssueID}) 183 repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}) 184 repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) 185 186 t.Run("UnrelatedCommentID", func(t *testing.T) { 187 // Using the ID of a comment that does not belong to the repository must fail 188 repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}) 189 repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) 190 token := getUserToken(t, repoOwner.Name, auth_model.AccessTokenScopeWriteIssue) 191 urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/comments/%d?token=%s", 192 repoOwner.Name, repo.Name, comment.ID, token) 193 req := NewRequestWithValues(t, "PATCH", urlStr, map[string]string{ 194 "body": newCommentBody, 195 }) 196 MakeRequest(t, req, http.StatusNotFound) 197 }) 198 199 token := getUserToken(t, repoOwner.Name, auth_model.AccessTokenScopeWriteIssue) 200 urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/comments/%d?token=%s", 201 repoOwner.Name, repo.Name, comment.ID, token) 202 req := NewRequestWithValues(t, "PATCH", urlStr, map[string]string{ 203 "body": newCommentBody, 204 }) 205 resp := MakeRequest(t, req, http.StatusOK) 206 207 var updatedComment api.Comment 208 DecodeJSON(t, resp, &updatedComment) 209 assert.EqualValues(t, comment.ID, updatedComment.ID) 210 assert.EqualValues(t, newCommentBody, updatedComment.Body) 211 unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: comment.ID, IssueID: issue.ID, Content: newCommentBody}) 212 } 213 214 func TestAPIDeleteComment(t *testing.T) { 215 defer tests.PrepareTestEnv(t)() 216 217 comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 8}, 218 unittest.Cond("type = ?", issues_model.CommentTypeComment)) 219 issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: comment.IssueID}) 220 repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}) 221 repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) 222 223 t.Run("UnrelatedCommentID", func(t *testing.T) { 224 // Using the ID of a comment that does not belong to the repository must fail 225 repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}) 226 repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) 227 token := getUserToken(t, repoOwner.Name, auth_model.AccessTokenScopeWriteIssue) 228 req := NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/issues/comments/%d?token=%s", 229 repoOwner.Name, repo.Name, comment.ID, token) 230 MakeRequest(t, req, http.StatusNotFound) 231 }) 232 233 token := getUserToken(t, repoOwner.Name, auth_model.AccessTokenScopeWriteIssue) 234 req := NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/issues/comments/%d?token=%s", 235 repoOwner.Name, repo.Name, comment.ID, token) 236 MakeRequest(t, req, http.StatusNoContent) 237 238 unittest.AssertNotExistsBean(t, &issues_model.Comment{ID: comment.ID}) 239 } 240 241 func TestAPIListIssueTimeline(t *testing.T) { 242 defer tests.PrepareTestEnv(t)() 243 244 // load comment 245 issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}) 246 repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}) 247 repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) 248 249 // make request 250 req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues/%d/timeline", 251 repoOwner.Name, repo.Name, issue.Index) 252 resp := MakeRequest(t, req, http.StatusOK) 253 254 // check if lens of list returned by API and 255 // lists extracted directly from DB are the same 256 var comments []*api.TimelineComment 257 DecodeJSON(t, resp, &comments) 258 expectedCount := unittest.GetCount(t, &issues_model.Comment{IssueID: issue.ID}) 259 assert.Len(t, comments, expectedCount) 260 }