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_xref_test.go 7.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. // Copyright 2019 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. "fmt"
  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. "code.gitea.io/gitea/modules/references"
  12. "github.com/stretchr/testify/assert"
  13. )
  14. func TestXRef_AddCrossReferences(t *testing.T) {
  15. assert.NoError(t, unittest.PrepareTestDatabase())
  16. // Issue #1 to test against
  17. itarget := testCreateIssue(t, 1, 2, "title1", "content1", false)
  18. // PR to close issue #1
  19. content := fmt.Sprintf("content2, closes #%d", itarget.Index)
  20. pr := testCreateIssue(t, 1, 2, "title2", content, true)
  21. ref := unittest.AssertExistsAndLoadBean(t, &Comment{IssueID: itarget.ID, RefIssueID: pr.ID, RefCommentID: 0}).(*Comment)
  22. assert.Equal(t, CommentTypePullRef, ref.Type)
  23. assert.Equal(t, pr.RepoID, ref.RefRepoID)
  24. assert.True(t, ref.RefIsPull)
  25. assert.Equal(t, references.XRefActionCloses, ref.RefAction)
  26. // Comment on PR to reopen issue #1
  27. content = fmt.Sprintf("content2, reopens #%d", itarget.Index)
  28. c := testCreateComment(t, 1, 2, pr.ID, content)
  29. ref = unittest.AssertExistsAndLoadBean(t, &Comment{IssueID: itarget.ID, RefIssueID: pr.ID, RefCommentID: c.ID}).(*Comment)
  30. assert.Equal(t, CommentTypeCommentRef, ref.Type)
  31. assert.Equal(t, pr.RepoID, ref.RefRepoID)
  32. assert.True(t, ref.RefIsPull)
  33. assert.Equal(t, references.XRefActionReopens, ref.RefAction)
  34. // Issue mentioning issue #1
  35. content = fmt.Sprintf("content3, mentions #%d", itarget.Index)
  36. i := testCreateIssue(t, 1, 2, "title3", content, false)
  37. ref = unittest.AssertExistsAndLoadBean(t, &Comment{IssueID: itarget.ID, RefIssueID: i.ID, RefCommentID: 0}).(*Comment)
  38. assert.Equal(t, CommentTypeIssueRef, ref.Type)
  39. assert.Equal(t, pr.RepoID, ref.RefRepoID)
  40. assert.False(t, ref.RefIsPull)
  41. assert.Equal(t, references.XRefActionNone, ref.RefAction)
  42. // Issue #4 to test against
  43. itarget = testCreateIssue(t, 3, 3, "title4", "content4", false)
  44. // Cross-reference to issue #4 by admin
  45. content = fmt.Sprintf("content5, mentions user3/repo3#%d", itarget.Index)
  46. i = testCreateIssue(t, 2, 1, "title5", content, false)
  47. ref = unittest.AssertExistsAndLoadBean(t, &Comment{IssueID: itarget.ID, RefIssueID: i.ID, RefCommentID: 0}).(*Comment)
  48. assert.Equal(t, CommentTypeIssueRef, ref.Type)
  49. assert.Equal(t, i.RepoID, ref.RefRepoID)
  50. assert.False(t, ref.RefIsPull)
  51. assert.Equal(t, references.XRefActionNone, ref.RefAction)
  52. // Cross-reference to issue #4 with no permission
  53. content = fmt.Sprintf("content6, mentions user3/repo3#%d", itarget.Index)
  54. i = testCreateIssue(t, 4, 5, "title6", content, false)
  55. unittest.AssertNotExistsBean(t, &Comment{IssueID: itarget.ID, RefIssueID: i.ID, RefCommentID: 0})
  56. }
  57. func TestXRef_NeuterCrossReferences(t *testing.T) {
  58. assert.NoError(t, unittest.PrepareTestDatabase())
  59. // Issue #1 to test against
  60. itarget := testCreateIssue(t, 1, 2, "title1", "content1", false)
  61. // Issue mentioning issue #1
  62. title := fmt.Sprintf("title2, mentions #%d", itarget.Index)
  63. i := testCreateIssue(t, 1, 2, title, "content2", false)
  64. ref := unittest.AssertExistsAndLoadBean(t, &Comment{IssueID: itarget.ID, RefIssueID: i.ID, RefCommentID: 0}).(*Comment)
  65. assert.Equal(t, CommentTypeIssueRef, ref.Type)
  66. assert.Equal(t, references.XRefActionNone, ref.RefAction)
  67. d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
  68. i.Title = "title2, no mentions"
  69. assert.NoError(t, i.ChangeTitle(d, title))
  70. ref = unittest.AssertExistsAndLoadBean(t, &Comment{IssueID: itarget.ID, RefIssueID: i.ID, RefCommentID: 0}).(*Comment)
  71. assert.Equal(t, CommentTypeIssueRef, ref.Type)
  72. assert.Equal(t, references.XRefActionNeutered, ref.RefAction)
  73. }
  74. func TestXRef_ResolveCrossReferences(t *testing.T) {
  75. assert.NoError(t, unittest.PrepareTestDatabase())
  76. d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
  77. i1 := testCreateIssue(t, 1, 2, "title1", "content1", false)
  78. i2 := testCreateIssue(t, 1, 2, "title2", "content2", false)
  79. i3 := testCreateIssue(t, 1, 2, "title3", "content3", false)
  80. _, err := i3.ChangeStatus(d, true)
  81. assert.NoError(t, err)
  82. pr := testCreatePR(t, 1, 2, "titlepr", fmt.Sprintf("closes #%d", i1.Index))
  83. rp := unittest.AssertExistsAndLoadBean(t, &Comment{IssueID: i1.ID, RefIssueID: pr.Issue.ID, RefCommentID: 0}).(*Comment)
  84. c1 := testCreateComment(t, 1, 2, pr.Issue.ID, fmt.Sprintf("closes #%d", i2.Index))
  85. r1 := unittest.AssertExistsAndLoadBean(t, &Comment{IssueID: i2.ID, RefIssueID: pr.Issue.ID, RefCommentID: c1.ID}).(*Comment)
  86. // Must be ignored
  87. c2 := testCreateComment(t, 1, 2, pr.Issue.ID, fmt.Sprintf("mentions #%d", i2.Index))
  88. unittest.AssertExistsAndLoadBean(t, &Comment{IssueID: i2.ID, RefIssueID: pr.Issue.ID, RefCommentID: c2.ID})
  89. // Must be superseded by c4/r4
  90. c3 := testCreateComment(t, 1, 2, pr.Issue.ID, fmt.Sprintf("reopens #%d", i3.Index))
  91. unittest.AssertExistsAndLoadBean(t, &Comment{IssueID: i3.ID, RefIssueID: pr.Issue.ID, RefCommentID: c3.ID})
  92. c4 := testCreateComment(t, 1, 2, pr.Issue.ID, fmt.Sprintf("closes #%d", i3.Index))
  93. r4 := unittest.AssertExistsAndLoadBean(t, &Comment{IssueID: i3.ID, RefIssueID: pr.Issue.ID, RefCommentID: c4.ID}).(*Comment)
  94. refs, err := pr.ResolveCrossReferences()
  95. assert.NoError(t, err)
  96. assert.Len(t, refs, 3)
  97. assert.Equal(t, rp.ID, refs[0].ID, "bad ref rp: %+v", refs[0])
  98. assert.Equal(t, r1.ID, refs[1].ID, "bad ref r1: %+v", refs[1])
  99. assert.Equal(t, r4.ID, refs[2].ID, "bad ref r4: %+v", refs[2])
  100. }
  101. func testCreateIssue(t *testing.T, repo, doer int64, title, content string, ispull bool) *Issue {
  102. r := unittest.AssertExistsAndLoadBean(t, &Repository{ID: repo}).(*Repository)
  103. d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: doer}).(*user_model.User)
  104. idx, err := db.GetNextResourceIndex("issue_index", r.ID)
  105. assert.NoError(t, err)
  106. i := &Issue{
  107. RepoID: r.ID,
  108. PosterID: d.ID,
  109. Poster: d,
  110. Title: title,
  111. Content: content,
  112. IsPull: ispull,
  113. Index: idx,
  114. }
  115. ctx, committer, err := db.TxContext()
  116. assert.NoError(t, err)
  117. defer committer.Close()
  118. err = newIssue(ctx, d, NewIssueOptions{
  119. Repo: r,
  120. Issue: i,
  121. })
  122. assert.NoError(t, err)
  123. i, err = getIssueByID(db.GetEngine(ctx), i.ID)
  124. assert.NoError(t, err)
  125. assert.NoError(t, i.addCrossReferences(ctx, d, false))
  126. assert.NoError(t, committer.Commit())
  127. return i
  128. }
  129. func testCreatePR(t *testing.T, repo, doer int64, title, content string) *PullRequest {
  130. r := unittest.AssertExistsAndLoadBean(t, &Repository{ID: repo}).(*Repository)
  131. d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: doer}).(*user_model.User)
  132. i := &Issue{RepoID: r.ID, PosterID: d.ID, Poster: d, Title: title, Content: content, IsPull: true}
  133. pr := &PullRequest{HeadRepoID: repo, BaseRepoID: repo, HeadBranch: "head", BaseBranch: "base", Status: PullRequestStatusMergeable}
  134. assert.NoError(t, NewPullRequest(r, i, nil, nil, pr))
  135. pr.Issue = i
  136. return pr
  137. }
  138. func testCreateComment(t *testing.T, repo, doer, issue int64, content string) *Comment {
  139. d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: doer}).(*user_model.User)
  140. i := unittest.AssertExistsAndLoadBean(t, &Issue{ID: issue}).(*Issue)
  141. c := &Comment{Type: CommentTypeComment, PosterID: doer, Poster: d, IssueID: issue, Issue: i, Content: content}
  142. ctx, committer, err := db.TxContext()
  143. assert.NoError(t, err)
  144. defer committer.Close()
  145. err = db.Insert(ctx, c)
  146. assert.NoError(t, err)
  147. assert.NoError(t, c.addCrossReferences(ctx, d, false))
  148. assert.NoError(t, committer.Commit())
  149. return c
  150. }