2019-11-18 13:13:07 +00:00
|
|
|
// Copyright 2019 The Gitea Authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a MIT-style
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
package models
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"testing"
|
|
|
|
|
2021-09-19 11:49:59 +00:00
|
|
|
"code.gitea.io/gitea/models/db"
|
2021-12-10 01:27:50 +00:00
|
|
|
repo_model "code.gitea.io/gitea/models/repo"
|
2021-11-12 14:36:47 +00:00
|
|
|
"code.gitea.io/gitea/models/unittest"
|
2021-11-24 09:49:20 +00:00
|
|
|
user_model "code.gitea.io/gitea/models/user"
|
2019-11-18 13:13:07 +00:00
|
|
|
"code.gitea.io/gitea/modules/references"
|
|
|
|
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestXRef_AddCrossReferences(t *testing.T) {
|
2021-11-12 14:36:47 +00:00
|
|
|
assert.NoError(t, unittest.PrepareTestDatabase())
|
2019-11-18 13:13:07 +00:00
|
|
|
|
|
|
|
// Issue #1 to test against
|
|
|
|
itarget := testCreateIssue(t, 1, 2, "title1", "content1", false)
|
|
|
|
|
|
|
|
// PR to close issue #1
|
|
|
|
content := fmt.Sprintf("content2, closes #%d", itarget.Index)
|
|
|
|
pr := testCreateIssue(t, 1, 2, "title2", content, true)
|
2021-11-16 08:53:21 +00:00
|
|
|
ref := unittest.AssertExistsAndLoadBean(t, &Comment{IssueID: itarget.ID, RefIssueID: pr.ID, RefCommentID: 0}).(*Comment)
|
2019-11-18 13:13:07 +00:00
|
|
|
assert.Equal(t, CommentTypePullRef, ref.Type)
|
|
|
|
assert.Equal(t, pr.RepoID, ref.RefRepoID)
|
2021-06-07 05:27:09 +00:00
|
|
|
assert.True(t, ref.RefIsPull)
|
2019-11-18 13:13:07 +00:00
|
|
|
assert.Equal(t, references.XRefActionCloses, ref.RefAction)
|
|
|
|
|
|
|
|
// Comment on PR to reopen issue #1
|
|
|
|
content = fmt.Sprintf("content2, reopens #%d", itarget.Index)
|
|
|
|
c := testCreateComment(t, 1, 2, pr.ID, content)
|
2021-11-16 08:53:21 +00:00
|
|
|
ref = unittest.AssertExistsAndLoadBean(t, &Comment{IssueID: itarget.ID, RefIssueID: pr.ID, RefCommentID: c.ID}).(*Comment)
|
2019-11-18 13:13:07 +00:00
|
|
|
assert.Equal(t, CommentTypeCommentRef, ref.Type)
|
|
|
|
assert.Equal(t, pr.RepoID, ref.RefRepoID)
|
2021-06-07 05:27:09 +00:00
|
|
|
assert.True(t, ref.RefIsPull)
|
2019-11-18 13:13:07 +00:00
|
|
|
assert.Equal(t, references.XRefActionReopens, ref.RefAction)
|
|
|
|
|
|
|
|
// Issue mentioning issue #1
|
|
|
|
content = fmt.Sprintf("content3, mentions #%d", itarget.Index)
|
|
|
|
i := testCreateIssue(t, 1, 2, "title3", content, false)
|
2021-11-16 08:53:21 +00:00
|
|
|
ref = unittest.AssertExistsAndLoadBean(t, &Comment{IssueID: itarget.ID, RefIssueID: i.ID, RefCommentID: 0}).(*Comment)
|
2019-11-18 13:13:07 +00:00
|
|
|
assert.Equal(t, CommentTypeIssueRef, ref.Type)
|
|
|
|
assert.Equal(t, pr.RepoID, ref.RefRepoID)
|
2021-06-07 05:27:09 +00:00
|
|
|
assert.False(t, ref.RefIsPull)
|
2019-11-18 13:13:07 +00:00
|
|
|
assert.Equal(t, references.XRefActionNone, ref.RefAction)
|
|
|
|
|
|
|
|
// Issue #4 to test against
|
|
|
|
itarget = testCreateIssue(t, 3, 3, "title4", "content4", false)
|
|
|
|
|
|
|
|
// Cross-reference to issue #4 by admin
|
|
|
|
content = fmt.Sprintf("content5, mentions user3/repo3#%d", itarget.Index)
|
|
|
|
i = testCreateIssue(t, 2, 1, "title5", content, false)
|
2021-11-16 08:53:21 +00:00
|
|
|
ref = unittest.AssertExistsAndLoadBean(t, &Comment{IssueID: itarget.ID, RefIssueID: i.ID, RefCommentID: 0}).(*Comment)
|
2019-11-18 13:13:07 +00:00
|
|
|
assert.Equal(t, CommentTypeIssueRef, ref.Type)
|
|
|
|
assert.Equal(t, i.RepoID, ref.RefRepoID)
|
2021-06-07 05:27:09 +00:00
|
|
|
assert.False(t, ref.RefIsPull)
|
2019-11-18 13:13:07 +00:00
|
|
|
assert.Equal(t, references.XRefActionNone, ref.RefAction)
|
|
|
|
|
|
|
|
// Cross-reference to issue #4 with no permission
|
|
|
|
content = fmt.Sprintf("content6, mentions user3/repo3#%d", itarget.Index)
|
|
|
|
i = testCreateIssue(t, 4, 5, "title6", content, false)
|
2021-11-16 08:53:21 +00:00
|
|
|
unittest.AssertNotExistsBean(t, &Comment{IssueID: itarget.ID, RefIssueID: i.ID, RefCommentID: 0})
|
2019-11-18 13:13:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestXRef_NeuterCrossReferences(t *testing.T) {
|
2021-11-12 14:36:47 +00:00
|
|
|
assert.NoError(t, unittest.PrepareTestDatabase())
|
2019-11-18 13:13:07 +00:00
|
|
|
|
|
|
|
// Issue #1 to test against
|
|
|
|
itarget := testCreateIssue(t, 1, 2, "title1", "content1", false)
|
|
|
|
|
|
|
|
// Issue mentioning issue #1
|
|
|
|
title := fmt.Sprintf("title2, mentions #%d", itarget.Index)
|
|
|
|
i := testCreateIssue(t, 1, 2, title, "content2", false)
|
2021-11-16 08:53:21 +00:00
|
|
|
ref := unittest.AssertExistsAndLoadBean(t, &Comment{IssueID: itarget.ID, RefIssueID: i.ID, RefCommentID: 0}).(*Comment)
|
2019-11-18 13:13:07 +00:00
|
|
|
assert.Equal(t, CommentTypeIssueRef, ref.Type)
|
|
|
|
assert.Equal(t, references.XRefActionNone, ref.RefAction)
|
|
|
|
|
2021-11-24 09:49:20 +00:00
|
|
|
d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
|
2019-11-18 13:13:07 +00:00
|
|
|
i.Title = "title2, no mentions"
|
|
|
|
assert.NoError(t, i.ChangeTitle(d, title))
|
|
|
|
|
2021-11-16 08:53:21 +00:00
|
|
|
ref = unittest.AssertExistsAndLoadBean(t, &Comment{IssueID: itarget.ID, RefIssueID: i.ID, RefCommentID: 0}).(*Comment)
|
2019-11-18 13:13:07 +00:00
|
|
|
assert.Equal(t, CommentTypeIssueRef, ref.Type)
|
|
|
|
assert.Equal(t, references.XRefActionNeutered, ref.RefAction)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestXRef_ResolveCrossReferences(t *testing.T) {
|
2021-11-12 14:36:47 +00:00
|
|
|
assert.NoError(t, unittest.PrepareTestDatabase())
|
2019-11-18 13:13:07 +00:00
|
|
|
|
2021-11-24 09:49:20 +00:00
|
|
|
d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
|
2019-11-18 13:13:07 +00:00
|
|
|
|
|
|
|
i1 := testCreateIssue(t, 1, 2, "title1", "content1", false)
|
|
|
|
i2 := testCreateIssue(t, 1, 2, "title2", "content2", false)
|
|
|
|
i3 := testCreateIssue(t, 1, 2, "title3", "content3", false)
|
2019-12-15 21:57:34 +00:00
|
|
|
_, err := i3.ChangeStatus(d, true)
|
|
|
|
assert.NoError(t, err)
|
2019-11-18 13:13:07 +00:00
|
|
|
|
|
|
|
pr := testCreatePR(t, 1, 2, "titlepr", fmt.Sprintf("closes #%d", i1.Index))
|
2021-11-16 08:53:21 +00:00
|
|
|
rp := unittest.AssertExistsAndLoadBean(t, &Comment{IssueID: i1.ID, RefIssueID: pr.Issue.ID, RefCommentID: 0}).(*Comment)
|
2019-11-18 13:13:07 +00:00
|
|
|
|
|
|
|
c1 := testCreateComment(t, 1, 2, pr.Issue.ID, fmt.Sprintf("closes #%d", i2.Index))
|
2021-11-16 08:53:21 +00:00
|
|
|
r1 := unittest.AssertExistsAndLoadBean(t, &Comment{IssueID: i2.ID, RefIssueID: pr.Issue.ID, RefCommentID: c1.ID}).(*Comment)
|
2019-11-18 13:13:07 +00:00
|
|
|
|
|
|
|
// Must be ignored
|
|
|
|
c2 := testCreateComment(t, 1, 2, pr.Issue.ID, fmt.Sprintf("mentions #%d", i2.Index))
|
2021-11-16 08:53:21 +00:00
|
|
|
unittest.AssertExistsAndLoadBean(t, &Comment{IssueID: i2.ID, RefIssueID: pr.Issue.ID, RefCommentID: c2.ID})
|
2019-11-18 13:13:07 +00:00
|
|
|
|
|
|
|
// Must be superseded by c4/r4
|
|
|
|
c3 := testCreateComment(t, 1, 2, pr.Issue.ID, fmt.Sprintf("reopens #%d", i3.Index))
|
2021-11-16 08:53:21 +00:00
|
|
|
unittest.AssertExistsAndLoadBean(t, &Comment{IssueID: i3.ID, RefIssueID: pr.Issue.ID, RefCommentID: c3.ID})
|
2019-11-18 13:13:07 +00:00
|
|
|
|
|
|
|
c4 := testCreateComment(t, 1, 2, pr.Issue.ID, fmt.Sprintf("closes #%d", i3.Index))
|
2021-11-16 08:53:21 +00:00
|
|
|
r4 := unittest.AssertExistsAndLoadBean(t, &Comment{IssueID: i3.ID, RefIssueID: pr.Issue.ID, RefCommentID: c4.ID}).(*Comment)
|
2019-11-18 13:13:07 +00:00
|
|
|
|
|
|
|
refs, err := pr.ResolveCrossReferences()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Len(t, refs, 3)
|
|
|
|
assert.Equal(t, rp.ID, refs[0].ID, "bad ref rp: %+v", refs[0])
|
|
|
|
assert.Equal(t, r1.ID, refs[1].ID, "bad ref r1: %+v", refs[1])
|
|
|
|
assert.Equal(t, r4.ID, refs[2].ID, "bad ref r4: %+v", refs[2])
|
|
|
|
}
|
|
|
|
|
|
|
|
func testCreateIssue(t *testing.T, repo, doer int64, title, content string, ispull bool) *Issue {
|
2021-12-10 01:27:50 +00:00
|
|
|
r := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repo}).(*repo_model.Repository)
|
2021-11-24 09:49:20 +00:00
|
|
|
d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: doer}).(*user_model.User)
|
2021-06-14 02:22:55 +00:00
|
|
|
|
2021-09-19 11:49:59 +00:00
|
|
|
idx, err := db.GetNextResourceIndex("issue_index", r.ID)
|
2021-06-14 02:22:55 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
i := &Issue{
|
|
|
|
RepoID: r.ID,
|
|
|
|
PosterID: d.ID,
|
|
|
|
Poster: d,
|
|
|
|
Title: title,
|
|
|
|
Content: content,
|
|
|
|
IsPull: ispull,
|
|
|
|
Index: idx,
|
|
|
|
}
|
2019-11-18 13:13:07 +00:00
|
|
|
|
2021-11-19 13:39:57 +00:00
|
|
|
ctx, committer, err := db.TxContext()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
defer committer.Close()
|
|
|
|
err = newIssue(ctx, d, NewIssueOptions{
|
2021-06-14 02:22:55 +00:00
|
|
|
Repo: r,
|
|
|
|
Issue: i,
|
|
|
|
})
|
2019-11-18 13:13:07 +00:00
|
|
|
assert.NoError(t, err)
|
2021-11-19 13:39:57 +00:00
|
|
|
i, err = getIssueByID(db.GetEngine(ctx), i.ID)
|
2019-11-18 13:13:07 +00:00
|
|
|
assert.NoError(t, err)
|
2021-11-19 13:39:57 +00:00
|
|
|
assert.NoError(t, i.addCrossReferences(ctx, d, false))
|
|
|
|
assert.NoError(t, committer.Commit())
|
2019-11-18 13:13:07 +00:00
|
|
|
return i
|
|
|
|
}
|
|
|
|
|
|
|
|
func testCreatePR(t *testing.T, repo, doer int64, title, content string) *PullRequest {
|
2021-12-10 01:27:50 +00:00
|
|
|
r := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repo}).(*repo_model.Repository)
|
2021-11-24 09:49:20 +00:00
|
|
|
d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: doer}).(*user_model.User)
|
2019-11-18 13:13:07 +00:00
|
|
|
i := &Issue{RepoID: r.ID, PosterID: d.ID, Poster: d, Title: title, Content: content, IsPull: true}
|
2019-12-13 22:21:06 +00:00
|
|
|
pr := &PullRequest{HeadRepoID: repo, BaseRepoID: repo, HeadBranch: "head", BaseBranch: "base", Status: PullRequestStatusMergeable}
|
|
|
|
assert.NoError(t, NewPullRequest(r, i, nil, nil, pr))
|
2019-11-18 13:13:07 +00:00
|
|
|
pr.Issue = i
|
|
|
|
return pr
|
|
|
|
}
|
|
|
|
|
|
|
|
func testCreateComment(t *testing.T, repo, doer, issue int64, content string) *Comment {
|
2021-11-24 09:49:20 +00:00
|
|
|
d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: doer}).(*user_model.User)
|
2021-11-16 08:53:21 +00:00
|
|
|
i := unittest.AssertExistsAndLoadBean(t, &Issue{ID: issue}).(*Issue)
|
2019-11-18 13:13:07 +00:00
|
|
|
c := &Comment{Type: CommentTypeComment, PosterID: doer, Poster: d, IssueID: issue, Issue: i, Content: content}
|
|
|
|
|
2021-11-19 13:39:57 +00:00
|
|
|
ctx, committer, err := db.TxContext()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
defer committer.Close()
|
|
|
|
err = db.Insert(ctx, c)
|
2019-11-18 13:13:07 +00:00
|
|
|
assert.NoError(t, err)
|
2021-11-19 13:39:57 +00:00
|
|
|
assert.NoError(t, c.addCrossReferences(ctx, d, false))
|
|
|
|
assert.NoError(t, committer.Commit())
|
2019-11-18 13:13:07 +00:00
|
|
|
return c
|
|
|
|
}
|