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.

issue_label_test.go 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  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 models
  5. import (
  6. "html/template"
  7. "testing"
  8. "code.gitea.io/gitea/models/db"
  9. "code.gitea.io/gitea/models/unittest"
  10. user_model "code.gitea.io/gitea/models/user"
  11. "github.com/stretchr/testify/assert"
  12. )
  13. // TODO TestGetLabelTemplateFile
  14. func TestLabel_CalOpenIssues(t *testing.T) {
  15. assert.NoError(t, unittest.PrepareTestDatabase())
  16. label := unittest.AssertExistsAndLoadBean(t, &Label{ID: 1}).(*Label)
  17. label.CalOpenIssues()
  18. assert.EqualValues(t, 2, label.NumOpenIssues)
  19. }
  20. func TestLabel_ForegroundColor(t *testing.T) {
  21. assert.NoError(t, unittest.PrepareTestDatabase())
  22. label := unittest.AssertExistsAndLoadBean(t, &Label{ID: 1}).(*Label)
  23. assert.Equal(t, template.CSS("#000"), label.ForegroundColor())
  24. label = unittest.AssertExistsAndLoadBean(t, &Label{ID: 2}).(*Label)
  25. assert.Equal(t, template.CSS("#fff"), label.ForegroundColor())
  26. }
  27. func TestNewLabels(t *testing.T) {
  28. assert.NoError(t, unittest.PrepareTestDatabase())
  29. labels := []*Label{
  30. {RepoID: 2, Name: "labelName2", Color: "#123456"},
  31. {RepoID: 3, Name: "labelName3", Color: "#23456F"},
  32. }
  33. assert.Error(t, NewLabel(&Label{RepoID: 3, Name: "invalid Color", Color: ""}))
  34. assert.Error(t, NewLabel(&Label{RepoID: 3, Name: "invalid Color", Color: "123456"}))
  35. assert.Error(t, NewLabel(&Label{RepoID: 3, Name: "invalid Color", Color: "#12345G"}))
  36. for _, label := range labels {
  37. unittest.AssertNotExistsBean(t, label)
  38. }
  39. assert.NoError(t, NewLabels(labels...))
  40. for _, label := range labels {
  41. unittest.AssertExistsAndLoadBean(t, label, unittest.Cond("id = ?", label.ID))
  42. }
  43. unittest.CheckConsistencyFor(t, &Label{}, &Repository{})
  44. }
  45. func TestGetLabelByID(t *testing.T) {
  46. assert.NoError(t, unittest.PrepareTestDatabase())
  47. label, err := GetLabelByID(1)
  48. assert.NoError(t, err)
  49. assert.EqualValues(t, 1, label.ID)
  50. _, err = GetLabelByID(unittest.NonexistentID)
  51. assert.True(t, IsErrLabelNotExist(err))
  52. }
  53. func TestGetLabelInRepoByName(t *testing.T) {
  54. assert.NoError(t, unittest.PrepareTestDatabase())
  55. label, err := GetLabelInRepoByName(1, "label1")
  56. assert.NoError(t, err)
  57. assert.EqualValues(t, 1, label.ID)
  58. assert.Equal(t, "label1", label.Name)
  59. _, err = GetLabelInRepoByName(1, "")
  60. assert.True(t, IsErrRepoLabelNotExist(err))
  61. _, err = GetLabelInRepoByName(unittest.NonexistentID, "nonexistent")
  62. assert.True(t, IsErrRepoLabelNotExist(err))
  63. }
  64. func TestGetLabelInRepoByNames(t *testing.T) {
  65. assert.NoError(t, unittest.PrepareTestDatabase())
  66. labelIDs, err := GetLabelIDsInRepoByNames(1, []string{"label1", "label2"})
  67. assert.NoError(t, err)
  68. assert.Len(t, labelIDs, 2)
  69. assert.Equal(t, int64(1), labelIDs[0])
  70. assert.Equal(t, int64(2), labelIDs[1])
  71. }
  72. func TestGetLabelInRepoByNamesDiscardsNonExistentLabels(t *testing.T) {
  73. assert.NoError(t, unittest.PrepareTestDatabase())
  74. // label3 doesn't exists.. See labels.yml
  75. labelIDs, err := GetLabelIDsInRepoByNames(1, []string{"label1", "label2", "label3"})
  76. assert.NoError(t, err)
  77. assert.Len(t, labelIDs, 2)
  78. assert.Equal(t, int64(1), labelIDs[0])
  79. assert.Equal(t, int64(2), labelIDs[1])
  80. assert.NoError(t, err)
  81. }
  82. func TestGetLabelInRepoByID(t *testing.T) {
  83. assert.NoError(t, unittest.PrepareTestDatabase())
  84. label, err := GetLabelInRepoByID(1, 1)
  85. assert.NoError(t, err)
  86. assert.EqualValues(t, 1, label.ID)
  87. _, err = GetLabelInRepoByID(1, -1)
  88. assert.True(t, IsErrRepoLabelNotExist(err))
  89. _, err = GetLabelInRepoByID(unittest.NonexistentID, unittest.NonexistentID)
  90. assert.True(t, IsErrRepoLabelNotExist(err))
  91. }
  92. func TestGetLabelsInRepoByIDs(t *testing.T) {
  93. assert.NoError(t, unittest.PrepareTestDatabase())
  94. labels, err := GetLabelsInRepoByIDs(1, []int64{1, 2, unittest.NonexistentID})
  95. assert.NoError(t, err)
  96. if assert.Len(t, labels, 2) {
  97. assert.EqualValues(t, 1, labels[0].ID)
  98. assert.EqualValues(t, 2, labels[1].ID)
  99. }
  100. }
  101. func TestGetLabelsByRepoID(t *testing.T) {
  102. assert.NoError(t, unittest.PrepareTestDatabase())
  103. testSuccess := func(repoID int64, sortType string, expectedIssueIDs []int64) {
  104. labels, err := GetLabelsByRepoID(repoID, sortType, db.ListOptions{})
  105. assert.NoError(t, err)
  106. assert.Len(t, labels, len(expectedIssueIDs))
  107. for i, label := range labels {
  108. assert.EqualValues(t, expectedIssueIDs[i], label.ID)
  109. }
  110. }
  111. testSuccess(1, "leastissues", []int64{2, 1})
  112. testSuccess(1, "mostissues", []int64{1, 2})
  113. testSuccess(1, "reversealphabetically", []int64{2, 1})
  114. testSuccess(1, "default", []int64{1, 2})
  115. }
  116. // Org versions
  117. func TestGetLabelInOrgByName(t *testing.T) {
  118. assert.NoError(t, unittest.PrepareTestDatabase())
  119. label, err := GetLabelInOrgByName(3, "orglabel3")
  120. assert.NoError(t, err)
  121. assert.EqualValues(t, 3, label.ID)
  122. assert.Equal(t, "orglabel3", label.Name)
  123. _, err = GetLabelInOrgByName(3, "")
  124. assert.True(t, IsErrOrgLabelNotExist(err))
  125. _, err = GetLabelInOrgByName(0, "orglabel3")
  126. assert.True(t, IsErrOrgLabelNotExist(err))
  127. _, err = GetLabelInOrgByName(-1, "orglabel3")
  128. assert.True(t, IsErrOrgLabelNotExist(err))
  129. _, err = GetLabelInOrgByName(unittest.NonexistentID, "nonexistent")
  130. assert.True(t, IsErrOrgLabelNotExist(err))
  131. }
  132. func TestGetLabelInOrgByNames(t *testing.T) {
  133. assert.NoError(t, unittest.PrepareTestDatabase())
  134. labelIDs, err := GetLabelIDsInOrgByNames(3, []string{"orglabel3", "orglabel4"})
  135. assert.NoError(t, err)
  136. assert.Len(t, labelIDs, 2)
  137. assert.Equal(t, int64(3), labelIDs[0])
  138. assert.Equal(t, int64(4), labelIDs[1])
  139. }
  140. func TestGetLabelInOrgByNamesDiscardsNonExistentLabels(t *testing.T) {
  141. assert.NoError(t, unittest.PrepareTestDatabase())
  142. // orglabel99 doesn't exists.. See labels.yml
  143. labelIDs, err := GetLabelIDsInOrgByNames(3, []string{"orglabel3", "orglabel4", "orglabel99"})
  144. assert.NoError(t, err)
  145. assert.Len(t, labelIDs, 2)
  146. assert.Equal(t, int64(3), labelIDs[0])
  147. assert.Equal(t, int64(4), labelIDs[1])
  148. assert.NoError(t, err)
  149. }
  150. func TestGetLabelInOrgByID(t *testing.T) {
  151. assert.NoError(t, unittest.PrepareTestDatabase())
  152. label, err := GetLabelInOrgByID(3, 3)
  153. assert.NoError(t, err)
  154. assert.EqualValues(t, 3, label.ID)
  155. _, err = GetLabelInOrgByID(3, -1)
  156. assert.True(t, IsErrOrgLabelNotExist(err))
  157. _, err = GetLabelInOrgByID(0, 3)
  158. assert.True(t, IsErrOrgLabelNotExist(err))
  159. _, err = GetLabelInOrgByID(-1, 3)
  160. assert.True(t, IsErrOrgLabelNotExist(err))
  161. _, err = GetLabelInOrgByID(unittest.NonexistentID, unittest.NonexistentID)
  162. assert.True(t, IsErrOrgLabelNotExist(err))
  163. }
  164. func TestGetLabelsInOrgByIDs(t *testing.T) {
  165. assert.NoError(t, unittest.PrepareTestDatabase())
  166. labels, err := GetLabelsInOrgByIDs(3, []int64{3, 4, unittest.NonexistentID})
  167. assert.NoError(t, err)
  168. if assert.Len(t, labels, 2) {
  169. assert.EqualValues(t, 3, labels[0].ID)
  170. assert.EqualValues(t, 4, labels[1].ID)
  171. }
  172. }
  173. func TestGetLabelsByOrgID(t *testing.T) {
  174. assert.NoError(t, unittest.PrepareTestDatabase())
  175. testSuccess := func(orgID int64, sortType string, expectedIssueIDs []int64) {
  176. labels, err := GetLabelsByOrgID(orgID, sortType, db.ListOptions{})
  177. assert.NoError(t, err)
  178. assert.Len(t, labels, len(expectedIssueIDs))
  179. for i, label := range labels {
  180. assert.EqualValues(t, expectedIssueIDs[i], label.ID)
  181. }
  182. }
  183. testSuccess(3, "leastissues", []int64{3, 4})
  184. testSuccess(3, "mostissues", []int64{4, 3})
  185. testSuccess(3, "reversealphabetically", []int64{4, 3})
  186. testSuccess(3, "default", []int64{3, 4})
  187. var err error
  188. _, err = GetLabelsByOrgID(0, "leastissues", db.ListOptions{})
  189. assert.True(t, IsErrOrgLabelNotExist(err))
  190. _, err = GetLabelsByOrgID(-1, "leastissues", db.ListOptions{})
  191. assert.True(t, IsErrOrgLabelNotExist(err))
  192. }
  193. //
  194. func TestGetLabelsByIssueID(t *testing.T) {
  195. assert.NoError(t, unittest.PrepareTestDatabase())
  196. labels, err := GetLabelsByIssueID(1)
  197. assert.NoError(t, err)
  198. if assert.Len(t, labels, 1) {
  199. assert.EqualValues(t, 1, labels[0].ID)
  200. }
  201. labels, err = GetLabelsByIssueID(unittest.NonexistentID)
  202. assert.NoError(t, err)
  203. assert.Len(t, labels, 0)
  204. }
  205. func TestUpdateLabel(t *testing.T) {
  206. assert.NoError(t, unittest.PrepareTestDatabase())
  207. label := unittest.AssertExistsAndLoadBean(t, &Label{ID: 1}).(*Label)
  208. // make sure update wont overwrite it
  209. update := &Label{
  210. ID: label.ID,
  211. Color: "#ffff00",
  212. Name: "newLabelName",
  213. Description: label.Description,
  214. }
  215. label.Color = update.Color
  216. label.Name = update.Name
  217. assert.NoError(t, UpdateLabel(update))
  218. newLabel := unittest.AssertExistsAndLoadBean(t, &Label{ID: 1}).(*Label)
  219. assert.EqualValues(t, label.ID, newLabel.ID)
  220. assert.EqualValues(t, label.Color, newLabel.Color)
  221. assert.EqualValues(t, label.Name, newLabel.Name)
  222. assert.EqualValues(t, label.Description, newLabel.Description)
  223. unittest.CheckConsistencyFor(t, &Label{}, &Repository{})
  224. }
  225. func TestDeleteLabel(t *testing.T) {
  226. assert.NoError(t, unittest.PrepareTestDatabase())
  227. label := unittest.AssertExistsAndLoadBean(t, &Label{ID: 1}).(*Label)
  228. assert.NoError(t, DeleteLabel(label.RepoID, label.ID))
  229. unittest.AssertNotExistsBean(t, &Label{ID: label.ID, RepoID: label.RepoID})
  230. assert.NoError(t, DeleteLabel(label.RepoID, label.ID))
  231. unittest.AssertNotExistsBean(t, &Label{ID: label.ID})
  232. assert.NoError(t, DeleteLabel(unittest.NonexistentID, unittest.NonexistentID))
  233. unittest.CheckConsistencyFor(t, &Label{}, &Repository{})
  234. }
  235. func TestHasIssueLabel(t *testing.T) {
  236. assert.NoError(t, unittest.PrepareTestDatabase())
  237. assert.True(t, HasIssueLabel(1, 1))
  238. assert.False(t, HasIssueLabel(1, 2))
  239. assert.False(t, HasIssueLabel(unittest.NonexistentID, unittest.NonexistentID))
  240. }
  241. func TestNewIssueLabel(t *testing.T) {
  242. assert.NoError(t, unittest.PrepareTestDatabase())
  243. label := unittest.AssertExistsAndLoadBean(t, &Label{ID: 2}).(*Label)
  244. issue := unittest.AssertExistsAndLoadBean(t, &Issue{ID: 1}).(*Issue)
  245. doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
  246. // add new IssueLabel
  247. prevNumIssues := label.NumIssues
  248. assert.NoError(t, NewIssueLabel(issue, label, doer))
  249. unittest.AssertExistsAndLoadBean(t, &IssueLabel{IssueID: issue.ID, LabelID: label.ID})
  250. unittest.AssertExistsAndLoadBean(t, &Comment{
  251. Type: CommentTypeLabel,
  252. PosterID: doer.ID,
  253. IssueID: issue.ID,
  254. LabelID: label.ID,
  255. Content: "1",
  256. })
  257. label = unittest.AssertExistsAndLoadBean(t, &Label{ID: 2}).(*Label)
  258. assert.EqualValues(t, prevNumIssues+1, label.NumIssues)
  259. // re-add existing IssueLabel
  260. assert.NoError(t, NewIssueLabel(issue, label, doer))
  261. unittest.CheckConsistencyFor(t, &Issue{}, &Label{})
  262. }
  263. func TestNewIssueLabels(t *testing.T) {
  264. assert.NoError(t, unittest.PrepareTestDatabase())
  265. label1 := unittest.AssertExistsAndLoadBean(t, &Label{ID: 1}).(*Label)
  266. label2 := unittest.AssertExistsAndLoadBean(t, &Label{ID: 2}).(*Label)
  267. issue := unittest.AssertExistsAndLoadBean(t, &Issue{ID: 5}).(*Issue)
  268. doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
  269. assert.NoError(t, NewIssueLabels(issue, []*Label{label1, label2}, doer))
  270. unittest.AssertExistsAndLoadBean(t, &IssueLabel{IssueID: issue.ID, LabelID: label1.ID})
  271. unittest.AssertExistsAndLoadBean(t, &Comment{
  272. Type: CommentTypeLabel,
  273. PosterID: doer.ID,
  274. IssueID: issue.ID,
  275. LabelID: label1.ID,
  276. Content: "1",
  277. })
  278. unittest.AssertExistsAndLoadBean(t, &IssueLabel{IssueID: issue.ID, LabelID: label1.ID})
  279. label1 = unittest.AssertExistsAndLoadBean(t, &Label{ID: 1}).(*Label)
  280. assert.EqualValues(t, 3, label1.NumIssues)
  281. assert.EqualValues(t, 1, label1.NumClosedIssues)
  282. label2 = unittest.AssertExistsAndLoadBean(t, &Label{ID: 2}).(*Label)
  283. assert.EqualValues(t, 1, label2.NumIssues)
  284. assert.EqualValues(t, 1, label2.NumClosedIssues)
  285. // corner case: test empty slice
  286. assert.NoError(t, NewIssueLabels(issue, []*Label{}, doer))
  287. unittest.CheckConsistencyFor(t, &Issue{}, &Label{})
  288. }
  289. func TestDeleteIssueLabel(t *testing.T) {
  290. assert.NoError(t, unittest.PrepareTestDatabase())
  291. testSuccess := func(labelID, issueID, doerID int64) {
  292. label := unittest.AssertExistsAndLoadBean(t, &Label{ID: labelID}).(*Label)
  293. issue := unittest.AssertExistsAndLoadBean(t, &Issue{ID: issueID}).(*Issue)
  294. doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: doerID}).(*user_model.User)
  295. expectedNumIssues := label.NumIssues
  296. expectedNumClosedIssues := label.NumClosedIssues
  297. if unittest.BeanExists(t, &IssueLabel{IssueID: issueID, LabelID: labelID}) {
  298. expectedNumIssues--
  299. if issue.IsClosed {
  300. expectedNumClosedIssues--
  301. }
  302. }
  303. assert.NoError(t, DeleteIssueLabel(issue, label, doer))
  304. unittest.AssertNotExistsBean(t, &IssueLabel{IssueID: issueID, LabelID: labelID})
  305. unittest.AssertExistsAndLoadBean(t, &Comment{
  306. Type: CommentTypeLabel,
  307. PosterID: doerID,
  308. IssueID: issueID,
  309. LabelID: labelID,
  310. }, `content=""`)
  311. label = unittest.AssertExistsAndLoadBean(t, &Label{ID: labelID}).(*Label)
  312. assert.EqualValues(t, expectedNumIssues, label.NumIssues)
  313. assert.EqualValues(t, expectedNumClosedIssues, label.NumClosedIssues)
  314. }
  315. testSuccess(1, 1, 2)
  316. testSuccess(2, 5, 2)
  317. testSuccess(1, 1, 2) // delete non-existent IssueLabel
  318. unittest.CheckConsistencyFor(t, &Issue{}, &Label{})
  319. }