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.

165 lines
6.9 KiB

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