mirror of https://github.com/go-gitea/gitea.git
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.
391 lines
13 KiB
391 lines
13 KiB
// Copyright 2017 The Gitea Authors. All rights reserved. |
|
// SPDX-License-Identifier: MIT |
|
|
|
package issues_test |
|
|
|
import ( |
|
"testing" |
|
|
|
"code.gitea.io/gitea/models/db" |
|
issues_model "code.gitea.io/gitea/models/issues" |
|
repo_model "code.gitea.io/gitea/models/repo" |
|
"code.gitea.io/gitea/models/unittest" |
|
user_model "code.gitea.io/gitea/models/user" |
|
"code.gitea.io/gitea/modules/setting" |
|
|
|
"github.com/stretchr/testify/assert" |
|
"github.com/stretchr/testify/require" |
|
) |
|
|
|
func TestPullRequest_LoadAttributes(t *testing.T) { |
|
assert.NoError(t, unittest.PrepareTestDatabase()) |
|
pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}) |
|
assert.NoError(t, pr.LoadAttributes(t.Context())) |
|
assert.NotNil(t, pr.Merger) |
|
assert.Equal(t, pr.MergerID, pr.Merger.ID) |
|
} |
|
|
|
func TestPullRequest_LoadIssue(t *testing.T) { |
|
assert.NoError(t, unittest.PrepareTestDatabase()) |
|
pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}) |
|
assert.NoError(t, pr.LoadIssue(t.Context())) |
|
assert.NotNil(t, pr.Issue) |
|
assert.Equal(t, int64(2), pr.Issue.ID) |
|
assert.NoError(t, pr.LoadIssue(t.Context())) |
|
assert.NotNil(t, pr.Issue) |
|
assert.Equal(t, int64(2), pr.Issue.ID) |
|
} |
|
|
|
func TestPullRequest_LoadBaseRepo(t *testing.T) { |
|
assert.NoError(t, unittest.PrepareTestDatabase()) |
|
pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}) |
|
assert.NoError(t, pr.LoadBaseRepo(t.Context())) |
|
assert.NotNil(t, pr.BaseRepo) |
|
assert.Equal(t, pr.BaseRepoID, pr.BaseRepo.ID) |
|
assert.NoError(t, pr.LoadBaseRepo(t.Context())) |
|
assert.NotNil(t, pr.BaseRepo) |
|
assert.Equal(t, pr.BaseRepoID, pr.BaseRepo.ID) |
|
} |
|
|
|
func TestPullRequest_LoadHeadRepo(t *testing.T) { |
|
assert.NoError(t, unittest.PrepareTestDatabase()) |
|
pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}) |
|
assert.NoError(t, pr.LoadHeadRepo(t.Context())) |
|
assert.NotNil(t, pr.HeadRepo) |
|
assert.Equal(t, pr.HeadRepoID, pr.HeadRepo.ID) |
|
} |
|
|
|
// TODO TestMerge |
|
|
|
// TODO TestNewPullRequest |
|
|
|
func TestPullRequestsNewest(t *testing.T) { |
|
assert.NoError(t, unittest.PrepareTestDatabase()) |
|
prs, count, err := issues_model.PullRequests(t.Context(), 1, &issues_model.PullRequestsOptions{ |
|
ListOptions: db.ListOptions{ |
|
Page: 1, |
|
}, |
|
State: "open", |
|
SortType: "newest", |
|
}) |
|
assert.NoError(t, err) |
|
assert.EqualValues(t, 3, count) |
|
if assert.Len(t, prs, 3) { |
|
assert.EqualValues(t, 5, prs[0].ID) |
|
assert.EqualValues(t, 2, prs[1].ID) |
|
assert.EqualValues(t, 1, prs[2].ID) |
|
} |
|
} |
|
|
|
func TestPullRequests_Closed_RecentSortType(t *testing.T) { |
|
// Issue ID | Closed At. | Updated At |
|
// 2 | 1707270001 | 1707270001 |
|
// 3 | 1707271000 | 1707279999 |
|
// 11 | 1707279999 | 1707275555 |
|
tests := []struct { |
|
sortType string |
|
expectedIssueIDOrder []int64 |
|
}{ |
|
{"recentupdate", []int64{3, 11, 2}}, |
|
{"recentclose", []int64{11, 3, 2}}, |
|
} |
|
|
|
assert.NoError(t, unittest.PrepareTestDatabase()) |
|
_, err := db.Exec(t.Context(), "UPDATE issue SET closed_unix = 1707270001, updated_unix = 1707270001, is_closed = true WHERE id = 2") |
|
require.NoError(t, err) |
|
_, err = db.Exec(t.Context(), "UPDATE issue SET closed_unix = 1707271000, updated_unix = 1707279999, is_closed = true WHERE id = 3") |
|
require.NoError(t, err) |
|
_, err = db.Exec(t.Context(), "UPDATE issue SET closed_unix = 1707279999, updated_unix = 1707275555, is_closed = true WHERE id = 11") |
|
require.NoError(t, err) |
|
|
|
for _, test := range tests { |
|
t.Run(test.sortType, func(t *testing.T) { |
|
prs, _, err := issues_model.PullRequests(t.Context(), 1, &issues_model.PullRequestsOptions{ |
|
ListOptions: db.ListOptions{ |
|
Page: 1, |
|
}, |
|
State: "closed", |
|
SortType: test.sortType, |
|
}) |
|
require.NoError(t, err) |
|
|
|
if assert.Len(t, prs, len(test.expectedIssueIDOrder)) { |
|
for i := range test.expectedIssueIDOrder { |
|
assert.Equal(t, test.expectedIssueIDOrder[i], prs[i].IssueID) |
|
} |
|
} |
|
}) |
|
} |
|
} |
|
|
|
func TestLoadRequestedReviewers(t *testing.T) { |
|
assert.NoError(t, unittest.PrepareTestDatabase()) |
|
|
|
pull := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}) |
|
assert.NoError(t, pull.LoadIssue(t.Context())) |
|
issue := pull.Issue |
|
assert.NoError(t, issue.LoadRepo(t.Context())) |
|
assert.Empty(t, pull.RequestedReviewers) |
|
|
|
user1, err := user_model.GetUserByID(t.Context(), 1) |
|
assert.NoError(t, err) |
|
|
|
comment, err := issues_model.AddReviewRequest(t.Context(), issue, user1, &user_model.User{}) |
|
assert.NoError(t, err) |
|
assert.NotNil(t, comment) |
|
|
|
assert.NoError(t, pull.LoadRequestedReviewers(t.Context())) |
|
assert.Len(t, pull.RequestedReviewers, 6) |
|
|
|
comment, err = issues_model.RemoveReviewRequest(t.Context(), issue, user1, &user_model.User{}) |
|
assert.NoError(t, err) |
|
assert.NotNil(t, comment) |
|
|
|
pull.RequestedReviewers = nil |
|
assert.NoError(t, pull.LoadRequestedReviewers(t.Context())) |
|
assert.Empty(t, pull.RequestedReviewers) |
|
} |
|
|
|
func TestPullRequestsOldest(t *testing.T) { |
|
assert.NoError(t, unittest.PrepareTestDatabase()) |
|
prs, count, err := issues_model.PullRequests(t.Context(), 1, &issues_model.PullRequestsOptions{ |
|
ListOptions: db.ListOptions{ |
|
Page: 1, |
|
}, |
|
State: "open", |
|
SortType: "oldest", |
|
}) |
|
assert.NoError(t, err) |
|
assert.EqualValues(t, 3, count) |
|
if assert.Len(t, prs, 3) { |
|
assert.EqualValues(t, 1, prs[0].ID) |
|
assert.EqualValues(t, 2, prs[1].ID) |
|
assert.EqualValues(t, 5, prs[2].ID) |
|
} |
|
} |
|
|
|
func TestGetUnmergedPullRequest(t *testing.T) { |
|
assert.NoError(t, unittest.PrepareTestDatabase()) |
|
pr, err := issues_model.GetUnmergedPullRequest(t.Context(), 1, 1, "branch2", "master", issues_model.PullRequestFlowGithub) |
|
assert.NoError(t, err) |
|
assert.Equal(t, int64(2), pr.ID) |
|
|
|
_, err = issues_model.GetUnmergedPullRequest(t.Context(), 1, 9223372036854775807, "branch1", "master", issues_model.PullRequestFlowGithub) |
|
assert.Error(t, err) |
|
assert.True(t, issues_model.IsErrPullRequestNotExist(err)) |
|
} |
|
|
|
func TestHasUnmergedPullRequestsByHeadInfo(t *testing.T) { |
|
assert.NoError(t, unittest.PrepareTestDatabase()) |
|
|
|
exist, err := issues_model.HasUnmergedPullRequestsByHeadInfo(t.Context(), 1, "branch2") |
|
assert.NoError(t, err) |
|
assert.True(t, exist) |
|
|
|
exist, err = issues_model.HasUnmergedPullRequestsByHeadInfo(t.Context(), 1, "not_exist_branch") |
|
assert.NoError(t, err) |
|
assert.False(t, exist) |
|
} |
|
|
|
func TestGetUnmergedPullRequestsByHeadInfo(t *testing.T) { |
|
assert.NoError(t, unittest.PrepareTestDatabase()) |
|
prs, err := issues_model.GetUnmergedPullRequestsByHeadInfo(t.Context(), 1, "branch2") |
|
assert.NoError(t, err) |
|
assert.Len(t, prs, 1) |
|
for _, pr := range prs { |
|
assert.Equal(t, int64(1), pr.HeadRepoID) |
|
assert.Equal(t, "branch2", pr.HeadBranch) |
|
} |
|
} |
|
|
|
func TestGetUnmergedPullRequestsByBaseInfo(t *testing.T) { |
|
assert.NoError(t, unittest.PrepareTestDatabase()) |
|
prs, err := issues_model.GetUnmergedPullRequestsByBaseInfo(t.Context(), 1, "master") |
|
assert.NoError(t, err) |
|
assert.Len(t, prs, 1) |
|
pr := prs[0] |
|
assert.Equal(t, int64(2), pr.ID) |
|
assert.Equal(t, int64(1), pr.BaseRepoID) |
|
assert.Equal(t, "master", pr.BaseBranch) |
|
} |
|
|
|
func TestGetPullRequestByIndex(t *testing.T) { |
|
assert.NoError(t, unittest.PrepareTestDatabase()) |
|
pr, err := issues_model.GetPullRequestByIndex(t.Context(), 1, 2) |
|
assert.NoError(t, err) |
|
assert.Equal(t, int64(1), pr.BaseRepoID) |
|
assert.Equal(t, int64(2), pr.Index) |
|
|
|
_, err = issues_model.GetPullRequestByIndex(t.Context(), 9223372036854775807, 9223372036854775807) |
|
assert.Error(t, err) |
|
assert.True(t, issues_model.IsErrPullRequestNotExist(err)) |
|
|
|
_, err = issues_model.GetPullRequestByIndex(t.Context(), 1, 0) |
|
assert.Error(t, err) |
|
assert.True(t, issues_model.IsErrPullRequestNotExist(err)) |
|
} |
|
|
|
func TestGetPullRequestByID(t *testing.T) { |
|
assert.NoError(t, unittest.PrepareTestDatabase()) |
|
pr, err := issues_model.GetPullRequestByID(t.Context(), 1) |
|
assert.NoError(t, err) |
|
assert.Equal(t, int64(1), pr.ID) |
|
assert.Equal(t, int64(2), pr.IssueID) |
|
|
|
_, err = issues_model.GetPullRequestByID(t.Context(), 9223372036854775807) |
|
assert.Error(t, err) |
|
assert.True(t, issues_model.IsErrPullRequestNotExist(err)) |
|
} |
|
|
|
func TestGetPullRequestByIssueID(t *testing.T) { |
|
assert.NoError(t, unittest.PrepareTestDatabase()) |
|
pr, err := issues_model.GetPullRequestByIssueID(t.Context(), 2) |
|
assert.NoError(t, err) |
|
assert.Equal(t, int64(2), pr.IssueID) |
|
|
|
_, err = issues_model.GetPullRequestByIssueID(t.Context(), 9223372036854775807) |
|
assert.Error(t, err) |
|
assert.True(t, issues_model.IsErrPullRequestNotExist(err)) |
|
} |
|
|
|
func TestPullRequest_UpdateCols(t *testing.T) { |
|
assert.NoError(t, unittest.PrepareTestDatabase()) |
|
pr := &issues_model.PullRequest{ |
|
ID: 1, |
|
BaseBranch: "baseBranch", |
|
HeadBranch: "headBranch", |
|
} |
|
assert.NoError(t, pr.UpdateCols(t.Context(), "head_branch")) |
|
|
|
pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}) |
|
assert.Equal(t, "master", pr.BaseBranch) |
|
assert.Equal(t, "headBranch", pr.HeadBranch) |
|
unittest.CheckConsistencyFor(t, pr) |
|
} |
|
|
|
// TODO TestAddTestPullRequestTask |
|
|
|
func TestPullRequest_IsWorkInProgress(t *testing.T) { |
|
assert.NoError(t, unittest.PrepareTestDatabase()) |
|
|
|
pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}) |
|
pr.LoadIssue(t.Context()) |
|
|
|
assert.False(t, pr.IsWorkInProgress(t.Context())) |
|
|
|
pr.Issue.Title = "WIP: " + pr.Issue.Title |
|
assert.True(t, pr.IsWorkInProgress(t.Context())) |
|
|
|
pr.Issue.Title = "[wip]: " + pr.Issue.Title |
|
assert.True(t, pr.IsWorkInProgress(t.Context())) |
|
} |
|
|
|
func TestPullRequest_GetWorkInProgressPrefixWorkInProgress(t *testing.T) { |
|
assert.NoError(t, unittest.PrepareTestDatabase()) |
|
|
|
pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}) |
|
pr.LoadIssue(t.Context()) |
|
|
|
assert.Empty(t, pr.GetWorkInProgressPrefix(t.Context())) |
|
|
|
original := pr.Issue.Title |
|
pr.Issue.Title = "WIP: " + original |
|
assert.Equal(t, "WIP:", pr.GetWorkInProgressPrefix(t.Context())) |
|
|
|
pr.Issue.Title = "[wip] " + original |
|
assert.Equal(t, "[wip]", pr.GetWorkInProgressPrefix(t.Context())) |
|
} |
|
|
|
func TestDeleteOrphanedObjects(t *testing.T) { |
|
assert.NoError(t, unittest.PrepareTestDatabase()) |
|
|
|
countBefore, err := db.GetEngine(t.Context()).Count(&issues_model.PullRequest{}) |
|
assert.NoError(t, err) |
|
|
|
_, err = db.GetEngine(t.Context()).Insert(&issues_model.PullRequest{IssueID: 1000}, &issues_model.PullRequest{IssueID: 1001}, &issues_model.PullRequest{IssueID: 1003}) |
|
assert.NoError(t, err) |
|
|
|
orphaned, err := db.CountOrphanedObjects(t.Context(), "pull_request", "issue", "pull_request.issue_id=issue.id") |
|
assert.NoError(t, err) |
|
assert.EqualValues(t, 3, orphaned) |
|
|
|
err = db.DeleteOrphanedObjects(t.Context(), "pull_request", "issue", "pull_request.issue_id=issue.id") |
|
assert.NoError(t, err) |
|
|
|
countAfter, err := db.GetEngine(t.Context()).Count(&issues_model.PullRequest{}) |
|
assert.NoError(t, err) |
|
assert.Equal(t, countBefore, countAfter) |
|
} |
|
|
|
func TestParseCodeOwnersLine(t *testing.T) { |
|
type CodeOwnerTest struct { |
|
Line string |
|
Tokens []string |
|
} |
|
|
|
given := []CodeOwnerTest{ |
|
{Line: "", Tokens: nil}, |
|
{Line: "# comment", Tokens: []string{}}, |
|
{Line: "!.* @user1 @org1/team1", Tokens: []string{"!.*", "@user1", "@org1/team1"}}, |
|
{Line: `.*\\.js @user2 #comment`, Tokens: []string{`.*\.js`, "@user2"}}, |
|
{Line: `docs/(aws|google|azure)/[^/]*\\.(md|txt) @org3 @org2/team2`, Tokens: []string{`docs/(aws|google|azure)/[^/]*\.(md|txt)`, "@org3", "@org2/team2"}}, |
|
{Line: `\#path @org3`, Tokens: []string{`#path`, "@org3"}}, |
|
{Line: `path\ with\ spaces/ @org3`, Tokens: []string{`path with spaces/`, "@org3"}}, |
|
} |
|
|
|
for _, g := range given { |
|
tokens := issues_model.TokenizeCodeOwnersLine(g.Line) |
|
assert.Equal(t, g.Tokens, tokens, "Codeowners tokenizer failed") |
|
} |
|
} |
|
|
|
func TestGetApprovers(t *testing.T) { |
|
assert.NoError(t, unittest.PrepareTestDatabase()) |
|
pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 5}) |
|
// Official reviews are already deduplicated. Allow unofficial reviews |
|
// to assert that there are no duplicated approvers. |
|
setting.Repository.PullRequest.DefaultMergeMessageOfficialApproversOnly = false |
|
approvers := pr.GetApprovers(t.Context()) |
|
expected := "Reviewed-by: User Five <user5@example.com>\nReviewed-by: Org Six <org6@example.com>\n" |
|
assert.Equal(t, expected, approvers) |
|
} |
|
|
|
func TestGetPullRequestByMergedCommit(t *testing.T) { |
|
assert.NoError(t, unittest.PrepareTestDatabase()) |
|
pr, err := issues_model.GetPullRequestByMergedCommit(t.Context(), 1, "1a8823cd1a9549fde083f992f6b9b87a7ab74fb3") |
|
assert.NoError(t, err) |
|
assert.EqualValues(t, 1, pr.ID) |
|
|
|
_, err = issues_model.GetPullRequestByMergedCommit(t.Context(), 0, "1a8823cd1a9549fde083f992f6b9b87a7ab74fb3") |
|
assert.ErrorAs(t, err, &issues_model.ErrPullRequestNotExist{}) |
|
_, err = issues_model.GetPullRequestByMergedCommit(t.Context(), 1, "") |
|
assert.ErrorAs(t, err, &issues_model.ErrPullRequestNotExist{}) |
|
} |
|
|
|
func TestMigrate_InsertPullRequests(t *testing.T) { |
|
assert.NoError(t, unittest.PrepareTestDatabase()) |
|
reponame := "repo1" |
|
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: reponame}) |
|
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) |
|
|
|
i := &issues_model.Issue{ |
|
RepoID: repo.ID, |
|
Repo: repo, |
|
Title: "title1", |
|
Content: "issuecontent1", |
|
IsPull: true, |
|
PosterID: owner.ID, |
|
Poster: owner, |
|
} |
|
|
|
p := &issues_model.PullRequest{ |
|
Issue: i, |
|
} |
|
|
|
err := issues_model.InsertPullRequests(t.Context(), p) |
|
assert.NoError(t, err) |
|
|
|
_ = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{IssueID: i.ID}) |
|
|
|
unittest.CheckConsistencyFor(t, &issues_model.Issue{}, &issues_model.PullRequest{}) |
|
}
|
|
|