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 12KB

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