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

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