You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

api_issue_test.go 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. // Copyright 2017 The Gitea Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package integrations
  5. import (
  6. "fmt"
  7. "net/http"
  8. "net/url"
  9. "testing"
  10. "time"
  11. "code.gitea.io/gitea/models"
  12. api "code.gitea.io/gitea/modules/structs"
  13. "github.com/stretchr/testify/assert"
  14. )
  15. func TestAPIListIssues(t *testing.T) {
  16. defer prepareTestEnv(t)()
  17. repo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 1}).(*models.Repository)
  18. owner := models.AssertExistsAndLoadBean(t, &models.User{ID: repo.OwnerID}).(*models.User)
  19. session := loginUser(t, owner.Name)
  20. token := getTokenForLoggedInUser(t, session)
  21. link, _ := url.Parse(fmt.Sprintf("/api/v1/repos/%s/%s/issues", owner.Name, repo.Name))
  22. link.RawQuery = url.Values{"token": {token}, "state": {"all"}}.Encode()
  23. resp := session.MakeRequest(t, NewRequest(t, "GET", link.String()), http.StatusOK)
  24. var apiIssues []*api.Issue
  25. DecodeJSON(t, resp, &apiIssues)
  26. assert.Len(t, apiIssues, models.GetCount(t, &models.Issue{RepoID: repo.ID}))
  27. for _, apiIssue := range apiIssues {
  28. models.AssertExistsAndLoadBean(t, &models.Issue{ID: apiIssue.ID, RepoID: repo.ID})
  29. }
  30. // test milestone filter
  31. link.RawQuery = url.Values{"token": {token}, "state": {"all"}, "type": {"all"}, "milestones": {"ignore,milestone1,3,4"}}.Encode()
  32. resp = session.MakeRequest(t, NewRequest(t, "GET", link.String()), http.StatusOK)
  33. DecodeJSON(t, resp, &apiIssues)
  34. if assert.Len(t, apiIssues, 2) {
  35. assert.EqualValues(t, 3, apiIssues[0].Milestone.ID)
  36. assert.EqualValues(t, 1, apiIssues[1].Milestone.ID)
  37. }
  38. link.RawQuery = url.Values{"token": {token}, "state": {"all"}, "created_by": {"user2"}}.Encode()
  39. resp = session.MakeRequest(t, NewRequest(t, "GET", link.String()), http.StatusOK)
  40. DecodeJSON(t, resp, &apiIssues)
  41. if assert.Len(t, apiIssues, 1) {
  42. assert.EqualValues(t, 5, apiIssues[0].ID)
  43. }
  44. link.RawQuery = url.Values{"token": {token}, "state": {"all"}, "assigned_by": {"user1"}}.Encode()
  45. resp = session.MakeRequest(t, NewRequest(t, "GET", link.String()), http.StatusOK)
  46. DecodeJSON(t, resp, &apiIssues)
  47. if assert.Len(t, apiIssues, 1) {
  48. assert.EqualValues(t, 1, apiIssues[0].ID)
  49. }
  50. link.RawQuery = url.Values{"token": {token}, "state": {"all"}, "mentioned_by": {"user4"}}.Encode()
  51. resp = session.MakeRequest(t, NewRequest(t, "GET", link.String()), http.StatusOK)
  52. DecodeJSON(t, resp, &apiIssues)
  53. if assert.Len(t, apiIssues, 1) {
  54. assert.EqualValues(t, 1, apiIssues[0].ID)
  55. }
  56. }
  57. func TestAPICreateIssue(t *testing.T) {
  58. defer prepareTestEnv(t)()
  59. const body, title = "apiTestBody", "apiTestTitle"
  60. repoBefore := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 1}).(*models.Repository)
  61. owner := models.AssertExistsAndLoadBean(t, &models.User{ID: repoBefore.OwnerID}).(*models.User)
  62. session := loginUser(t, owner.Name)
  63. token := getTokenForLoggedInUser(t, session)
  64. urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues?state=all&token=%s", owner.Name, repoBefore.Name, token)
  65. req := NewRequestWithJSON(t, "POST", urlStr, &api.CreateIssueOption{
  66. Body: body,
  67. Title: title,
  68. Assignee: owner.Name,
  69. })
  70. resp := session.MakeRequest(t, req, http.StatusCreated)
  71. var apiIssue api.Issue
  72. DecodeJSON(t, resp, &apiIssue)
  73. assert.Equal(t, body, apiIssue.Body)
  74. assert.Equal(t, title, apiIssue.Title)
  75. models.AssertExistsAndLoadBean(t, &models.Issue{
  76. RepoID: repoBefore.ID,
  77. AssigneeID: owner.ID,
  78. Content: body,
  79. Title: title,
  80. })
  81. repoAfter := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 1}).(*models.Repository)
  82. assert.Equal(t, repoBefore.NumIssues+1, repoAfter.NumIssues)
  83. assert.Equal(t, repoBefore.NumClosedIssues, repoAfter.NumClosedIssues)
  84. }
  85. func TestAPIEditIssue(t *testing.T) {
  86. defer prepareTestEnv(t)()
  87. issueBefore := models.AssertExistsAndLoadBean(t, &models.Issue{ID: 10}).(*models.Issue)
  88. repoBefore := models.AssertExistsAndLoadBean(t, &models.Repository{ID: issueBefore.RepoID}).(*models.Repository)
  89. owner := models.AssertExistsAndLoadBean(t, &models.User{ID: repoBefore.OwnerID}).(*models.User)
  90. assert.NoError(t, issueBefore.LoadAttributes())
  91. assert.Equal(t, int64(1019307200), int64(issueBefore.DeadlineUnix))
  92. assert.Equal(t, api.StateOpen, issueBefore.State())
  93. session := loginUser(t, owner.Name)
  94. token := getTokenForLoggedInUser(t, session)
  95. // update values of issue
  96. issueState := "closed"
  97. removeDeadline := true
  98. milestone := int64(4)
  99. body := "new content!"
  100. title := "new title from api set"
  101. urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d?token=%s", owner.Name, repoBefore.Name, issueBefore.Index, token)
  102. req := NewRequestWithJSON(t, "PATCH", urlStr, api.EditIssueOption{
  103. State: &issueState,
  104. RemoveDeadline: &removeDeadline,
  105. Milestone: &milestone,
  106. Body: &body,
  107. Title: title,
  108. // ToDo change more
  109. })
  110. resp := session.MakeRequest(t, req, http.StatusCreated)
  111. var apiIssue api.Issue
  112. DecodeJSON(t, resp, &apiIssue)
  113. issueAfter := models.AssertExistsAndLoadBean(t, &models.Issue{ID: 10}).(*models.Issue)
  114. repoAfter := models.AssertExistsAndLoadBean(t, &models.Repository{ID: issueBefore.RepoID}).(*models.Repository)
  115. // check deleted user
  116. assert.Equal(t, int64(500), issueAfter.PosterID)
  117. assert.NoError(t, issueAfter.LoadAttributes())
  118. assert.Equal(t, int64(-1), issueAfter.PosterID)
  119. assert.Equal(t, int64(-1), issueBefore.PosterID)
  120. assert.Equal(t, int64(-1), apiIssue.Poster.ID)
  121. // check repo change
  122. assert.Equal(t, repoBefore.NumClosedIssues+1, repoAfter.NumClosedIssues)
  123. // API response
  124. assert.Equal(t, api.StateClosed, apiIssue.State)
  125. assert.Equal(t, milestone, apiIssue.Milestone.ID)
  126. assert.Equal(t, body, apiIssue.Body)
  127. assert.True(t, apiIssue.Deadline == nil)
  128. assert.Equal(t, title, apiIssue.Title)
  129. // in database
  130. assert.Equal(t, api.StateClosed, issueAfter.State())
  131. assert.Equal(t, milestone, issueAfter.MilestoneID)
  132. assert.Equal(t, int64(0), int64(issueAfter.DeadlineUnix))
  133. assert.Equal(t, body, issueAfter.Content)
  134. assert.Equal(t, title, issueAfter.Title)
  135. }
  136. func TestAPISearchIssues(t *testing.T) {
  137. defer prepareTestEnv(t)()
  138. session := loginUser(t, "user2")
  139. token := getTokenForLoggedInUser(t, session)
  140. link, _ := url.Parse("/api/v1/repos/issues/search")
  141. req := NewRequest(t, "GET", link.String())
  142. resp := session.MakeRequest(t, req, http.StatusOK)
  143. var apiIssues []*api.Issue
  144. DecodeJSON(t, resp, &apiIssues)
  145. assert.Len(t, apiIssues, 10)
  146. query := url.Values{"token": {token}}
  147. link.RawQuery = query.Encode()
  148. req = NewRequest(t, "GET", link.String())
  149. resp = session.MakeRequest(t, req, http.StatusOK)
  150. DecodeJSON(t, resp, &apiIssues)
  151. assert.Len(t, apiIssues, 10)
  152. since := "2000-01-01T00%3A50%3A01%2B00%3A00" // 946687801
  153. before := time.Unix(999307200, 0).Format(time.RFC3339)
  154. query.Add("since", since)
  155. query.Add("before", before)
  156. link.RawQuery = query.Encode()
  157. req = NewRequest(t, "GET", link.String())
  158. resp = session.MakeRequest(t, req, http.StatusOK)
  159. DecodeJSON(t, resp, &apiIssues)
  160. assert.Len(t, apiIssues, 8)
  161. query.Del("since")
  162. query.Del("before")
  163. query.Add("state", "closed")
  164. link.RawQuery = query.Encode()
  165. req = NewRequest(t, "GET", link.String())
  166. resp = session.MakeRequest(t, req, http.StatusOK)
  167. DecodeJSON(t, resp, &apiIssues)
  168. assert.Len(t, apiIssues, 2)
  169. query.Set("state", "all")
  170. link.RawQuery = query.Encode()
  171. req = NewRequest(t, "GET", link.String())
  172. resp = session.MakeRequest(t, req, http.StatusOK)
  173. DecodeJSON(t, resp, &apiIssues)
  174. assert.EqualValues(t, "15", resp.Header().Get("X-Total-Count"))
  175. assert.Len(t, apiIssues, 10) //there are more but 10 is page item limit
  176. query.Add("limit", "20")
  177. link.RawQuery = query.Encode()
  178. req = NewRequest(t, "GET", link.String())
  179. resp = session.MakeRequest(t, req, http.StatusOK)
  180. DecodeJSON(t, resp, &apiIssues)
  181. assert.Len(t, apiIssues, 15)
  182. query = url.Values{"assigned": {"true"}, "state": {"all"}}
  183. link.RawQuery = query.Encode()
  184. req = NewRequest(t, "GET", link.String())
  185. resp = session.MakeRequest(t, req, http.StatusOK)
  186. DecodeJSON(t, resp, &apiIssues)
  187. assert.Len(t, apiIssues, 1)
  188. query = url.Values{"milestones": {"milestone1"}, "state": {"all"}}
  189. link.RawQuery = query.Encode()
  190. req = NewRequest(t, "GET", link.String())
  191. resp = session.MakeRequest(t, req, http.StatusOK)
  192. DecodeJSON(t, resp, &apiIssues)
  193. assert.Len(t, apiIssues, 1)
  194. query = url.Values{"milestones": {"milestone1,milestone3"}, "state": {"all"}}
  195. link.RawQuery = query.Encode()
  196. req = NewRequest(t, "GET", link.String())
  197. resp = session.MakeRequest(t, req, http.StatusOK)
  198. DecodeJSON(t, resp, &apiIssues)
  199. assert.Len(t, apiIssues, 2)
  200. query = url.Values{"owner": {"user2"}} // user
  201. link.RawQuery = query.Encode()
  202. req = NewRequest(t, "GET", link.String())
  203. resp = session.MakeRequest(t, req, http.StatusOK)
  204. DecodeJSON(t, resp, &apiIssues)
  205. assert.Len(t, apiIssues, 6)
  206. query = url.Values{"owner": {"user3"}} // organization
  207. link.RawQuery = query.Encode()
  208. req = NewRequest(t, "GET", link.String())
  209. resp = session.MakeRequest(t, req, http.StatusOK)
  210. DecodeJSON(t, resp, &apiIssues)
  211. assert.Len(t, apiIssues, 3)
  212. query = url.Values{"owner": {"user3"}, "team": {"team1"}} // organization + team
  213. link.RawQuery = query.Encode()
  214. req = NewRequest(t, "GET", link.String())
  215. resp = session.MakeRequest(t, req, http.StatusOK)
  216. DecodeJSON(t, resp, &apiIssues)
  217. assert.Len(t, apiIssues, 2)
  218. }
  219. func TestAPISearchIssuesWithLabels(t *testing.T) {
  220. defer prepareTestEnv(t)()
  221. session := loginUser(t, "user1")
  222. token := getTokenForLoggedInUser(t, session)
  223. link, _ := url.Parse("/api/v1/repos/issues/search")
  224. req := NewRequest(t, "GET", link.String())
  225. resp := session.MakeRequest(t, req, http.StatusOK)
  226. var apiIssues []*api.Issue
  227. DecodeJSON(t, resp, &apiIssues)
  228. assert.Len(t, apiIssues, 10)
  229. query := url.Values{}
  230. query.Add("token", token)
  231. link.RawQuery = query.Encode()
  232. req = NewRequest(t, "GET", link.String())
  233. resp = session.MakeRequest(t, req, http.StatusOK)
  234. DecodeJSON(t, resp, &apiIssues)
  235. assert.Len(t, apiIssues, 10)
  236. query.Add("labels", "label1")
  237. link.RawQuery = query.Encode()
  238. req = NewRequest(t, "GET", link.String())
  239. resp = session.MakeRequest(t, req, http.StatusOK)
  240. DecodeJSON(t, resp, &apiIssues)
  241. assert.Len(t, apiIssues, 2)
  242. // multiple labels
  243. query.Set("labels", "label1,label2")
  244. link.RawQuery = query.Encode()
  245. req = NewRequest(t, "GET", link.String())
  246. resp = session.MakeRequest(t, req, http.StatusOK)
  247. DecodeJSON(t, resp, &apiIssues)
  248. assert.Len(t, apiIssues, 2)
  249. // an org label
  250. query.Set("labels", "orglabel4")
  251. link.RawQuery = query.Encode()
  252. req = NewRequest(t, "GET", link.String())
  253. resp = session.MakeRequest(t, req, http.StatusOK)
  254. DecodeJSON(t, resp, &apiIssues)
  255. assert.Len(t, apiIssues, 1)
  256. // org and repo label
  257. query.Set("labels", "label2,orglabel4")
  258. query.Add("state", "all")
  259. link.RawQuery = query.Encode()
  260. req = NewRequest(t, "GET", link.String())
  261. resp = session.MakeRequest(t, req, http.StatusOK)
  262. DecodeJSON(t, resp, &apiIssues)
  263. assert.Len(t, apiIssues, 2)
  264. // org and repo label which share the same issue
  265. query.Set("labels", "label1,orglabel4")
  266. link.RawQuery = query.Encode()
  267. req = NewRequest(t, "GET", link.String())
  268. resp = session.MakeRequest(t, req, http.StatusOK)
  269. DecodeJSON(t, resp, &apiIssues)
  270. assert.Len(t, apiIssues, 2)
  271. }