Files
forge/services/issue/commit_test.go
zeekayandHanzo Dev aa87442fdd Record upstream authorship centrally in NOTICE instead of in every file header
Source files keep their SPDX-License-Identifier and Hanzo copyright line; the
Gitea, Gogs and LFS Test Server copyrights they used to repeat now live once in
NOTICE, alongside LICENSE. The header lint accepts any copyright line above the
SPDX line, so it no longer demands an upstream one.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-10 17:50:35 -07:00

357 lines
12 KiB
Go

// Copyright 2026 Hanzo AI, Inc. All rights reserved.
// SPDX-License-Identifier: MIT
package issue
import (
"testing"
activities_model "github.com/hanzoai/git/models/activities"
issues_model "github.com/hanzoai/git/models/issues"
repo_model "github.com/hanzoai/git/models/repo"
"github.com/hanzoai/git/models/unittest"
user_model "github.com/hanzoai/git/models/user"
"github.com/hanzoai/git/modules/repository"
"github.com/hanzoai/git/modules/setting"
"github.com/stretchr/testify/assert"
)
func TestUpdateIssuesCommit(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
pushCommits := []*repository.PushCommit{
{
Sha1: "abcdef1",
CommitterEmail: "[email protected]",
CommitterName: "User Two",
AuthorEmail: "[email protected]",
AuthorName: "User Four",
Message: "start working on #FST-1, #1",
},
{
Sha1: "abcdef2",
CommitterEmail: "[email protected]",
CommitterName: "User Two",
AuthorEmail: "[email protected]",
AuthorName: "User Two",
Message: "a plain message",
},
{
Sha1: "abcdef2",
CommitterEmail: "[email protected]",
CommitterName: "User Two",
AuthorEmail: "[email protected]",
AuthorName: "User Two",
Message: "close #2",
},
}
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
repo.Owner = user
commentBean := &issues_model.Comment{
Type: issues_model.CommentTypeCommitRef,
CommitSHA: "abcdef1",
PosterID: user.ID,
IssueID: 1,
}
issueBean := &issues_model.Issue{RepoID: repo.ID, Index: 4}
unittest.AssertNotExistsBean(t, commentBean)
unittest.AssertNotExistsBean(t, &issues_model.Issue{RepoID: repo.ID, Index: 2}, "is_closed=1")
assert.NoError(t, UpdateIssuesCommit(t.Context(), user, repo, pushCommits, repo.DefaultBranch))
unittest.AssertExistsAndLoadBean(t, commentBean)
unittest.AssertExistsAndLoadBean(t, issueBean, "is_closed=1")
unittest.CheckConsistencyFor(t, &activities_model.Action{})
// Test that push to a non-default branch closes no issue.
pushCommits = []*repository.PushCommit{
{
Sha1: "abcdef1",
CommitterEmail: "[email protected]",
CommitterName: "User Two",
AuthorEmail: "[email protected]",
AuthorName: "User Four",
Message: "close #1",
},
}
repo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3})
commentBean = &issues_model.Comment{
Type: issues_model.CommentTypeCommitRef,
CommitSHA: "abcdef1",
PosterID: user.ID,
IssueID: 6,
}
issueBean = &issues_model.Issue{RepoID: repo.ID, Index: 1}
unittest.AssertNotExistsBean(t, commentBean)
unittest.AssertNotExistsBean(t, &issues_model.Issue{RepoID: repo.ID, Index: 1}, "is_closed=1")
assert.NoError(t, UpdateIssuesCommit(t.Context(), user, repo, pushCommits, "non-existing-branch"))
unittest.AssertExistsAndLoadBean(t, commentBean)
unittest.AssertNotExistsBean(t, issueBean, "is_closed=1")
unittest.CheckConsistencyFor(t, &activities_model.Action{})
pushCommits = []*repository.PushCommit{
{
Sha1: "abcdef3",
CommitterEmail: "[email protected]",
CommitterName: "User Two",
AuthorEmail: "[email protected]",
AuthorName: "User Two",
Message: "close " + setting.AppURL + repo.FullName() + "/pulls/1",
},
}
repo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3})
commentBean = &issues_model.Comment{
Type: issues_model.CommentTypeCommitRef,
CommitSHA: "abcdef3",
PosterID: user.ID,
IssueID: 6,
}
issueBean = &issues_model.Issue{RepoID: repo.ID, Index: 1}
unittest.AssertNotExistsBean(t, commentBean)
unittest.AssertNotExistsBean(t, &issues_model.Issue{RepoID: repo.ID, Index: 1}, "is_closed=1")
assert.NoError(t, UpdateIssuesCommit(t.Context(), user, repo, pushCommits, repo.DefaultBranch))
unittest.AssertExistsAndLoadBean(t, commentBean)
unittest.AssertExistsAndLoadBean(t, issueBean, "is_closed=1")
unittest.CheckConsistencyFor(t, &activities_model.Action{})
}
func TestUpdateIssuesCommit_Colon(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
pushCommits := []*repository.PushCommit{
{
Sha1: "abcdef2",
CommitterEmail: "[email protected]",
CommitterName: "User Two",
AuthorEmail: "[email protected]",
AuthorName: "User Two",
Message: "close: #2",
},
}
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
repo.Owner = user
issueBean := &issues_model.Issue{RepoID: repo.ID, Index: 4}
unittest.AssertNotExistsBean(t, &issues_model.Issue{RepoID: repo.ID, Index: 2}, "is_closed=1")
assert.NoError(t, UpdateIssuesCommit(t.Context(), user, repo, pushCommits, repo.DefaultBranch))
unittest.AssertExistsAndLoadBean(t, issueBean, "is_closed=1")
unittest.CheckConsistencyFor(t, &activities_model.Action{})
}
func TestUpdateIssuesCommit_Issue5957(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
// Test that push to a non-default branch closes an issue.
pushCommits := []*repository.PushCommit{
{
Sha1: "abcdef1",
CommitterEmail: "[email protected]",
CommitterName: "User Two",
AuthorEmail: "[email protected]",
AuthorName: "User Four",
Message: "close #2",
},
}
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
commentBean := &issues_model.Comment{
Type: issues_model.CommentTypeCommitRef,
CommitSHA: "abcdef1",
PosterID: user.ID,
IssueID: 7,
}
issueBean := &issues_model.Issue{RepoID: repo.ID, Index: 2, ID: 7}
unittest.AssertNotExistsBean(t, commentBean)
unittest.AssertNotExistsBean(t, issueBean, "is_closed=1")
assert.NoError(t, UpdateIssuesCommit(t.Context(), user, repo, pushCommits, "non-existing-branch"))
unittest.AssertExistsAndLoadBean(t, commentBean)
unittest.AssertExistsAndLoadBean(t, issueBean, "is_closed=1")
unittest.CheckConsistencyFor(t, &activities_model.Action{})
}
func TestUpdateIssuesCommit_AnotherRepo(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
// Test that a push to default branch closes issue in another repo
// If the user also has push permissions to that repo
pushCommits := []*repository.PushCommit{
{
Sha1: "abcdef1",
CommitterEmail: "[email protected]",
CommitterName: "User Two",
AuthorEmail: "[email protected]",
AuthorName: "User Two",
Message: "close user2/repo1#1",
},
}
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
commentBean := &issues_model.Comment{
Type: issues_model.CommentTypeCommitRef,
CommitSHA: "abcdef1",
PosterID: user.ID,
IssueID: 1,
}
issueBean := &issues_model.Issue{RepoID: 1, Index: 1, ID: 1}
unittest.AssertNotExistsBean(t, commentBean)
unittest.AssertNotExistsBean(t, issueBean, "is_closed=1")
assert.NoError(t, UpdateIssuesCommit(t.Context(), user, repo, pushCommits, repo.DefaultBranch))
unittest.AssertExistsAndLoadBean(t, commentBean)
unittest.AssertExistsAndLoadBean(t, issueBean, "is_closed=1")
unittest.CheckConsistencyFor(t, &activities_model.Action{})
}
func TestUpdateIssuesCommit_AnotherRepo_FullAddress(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
// Test that a push to default branch closes issue in another repo
// If the user also has push permissions to that repo
pushCommits := []*repository.PushCommit{
{
Sha1: "abcdef1",
CommitterEmail: "[email protected]",
CommitterName: "User Two",
AuthorEmail: "[email protected]",
AuthorName: "User Two",
Message: "close " + setting.AppURL + "user2/repo1/issues/1",
},
}
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
commentBean := &issues_model.Comment{
Type: issues_model.CommentTypeCommitRef,
CommitSHA: "abcdef1",
PosterID: user.ID,
IssueID: 1,
}
issueBean := &issues_model.Issue{RepoID: 1, Index: 1, ID: 1}
unittest.AssertNotExistsBean(t, commentBean)
unittest.AssertNotExistsBean(t, issueBean, "is_closed=1")
assert.NoError(t, UpdateIssuesCommit(t.Context(), user, repo, pushCommits, repo.DefaultBranch))
unittest.AssertExistsAndLoadBean(t, commentBean)
unittest.AssertExistsAndLoadBean(t, issueBean, "is_closed=1")
unittest.CheckConsistencyFor(t, &activities_model.Action{})
}
func TestUpdateIssuesCommit_AnotherRepoNoPermission(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 10})
// Test that a push with close reference *can not* close issue
// If the committer doesn't have push rights in that repo
pushCommits := []*repository.PushCommit{
{
Sha1: "abcdef3",
CommitterEmail: "[email protected]",
CommitterName: "User Ten",
AuthorEmail: "[email protected]",
AuthorName: "User Ten",
Message: "close org3/repo3#1",
},
{
Sha1: "abcdef4",
CommitterEmail: "[email protected]",
CommitterName: "User Ten",
AuthorEmail: "[email protected]",
AuthorName: "User Ten",
Message: "close " + setting.AppURL + "org3/repo3/issues/1",
},
}
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 6})
commentBean := &issues_model.Comment{
Type: issues_model.CommentTypeCommitRef,
CommitSHA: "abcdef3",
PosterID: user.ID,
IssueID: 6,
}
commentBean2 := &issues_model.Comment{
Type: issues_model.CommentTypeCommitRef,
CommitSHA: "abcdef4",
PosterID: user.ID,
IssueID: 6,
}
issueBean := &issues_model.Issue{RepoID: 3, Index: 1, ID: 6}
unittest.AssertNotExistsBean(t, commentBean)
unittest.AssertNotExistsBean(t, commentBean2)
unittest.AssertNotExistsBean(t, issueBean, "is_closed=1")
assert.NoError(t, UpdateIssuesCommit(t.Context(), user, repo, pushCommits, repo.DefaultBranch))
unittest.AssertNotExistsBean(t, commentBean)
unittest.AssertNotExistsBean(t, commentBean2)
unittest.AssertNotExistsBean(t, issueBean, "is_closed=1")
unittest.CheckConsistencyFor(t, &activities_model.Action{})
}
func TestUpdateIssuesCommit_SelfReference(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
// Test that a PR merge commit that references its own PR does not create a self-reference comment
// PR #2 (issue_id=2) has merged_commit_id: 1a8823cd1a9549fde083f992f6b9b87a7ab74fb3
pushCommits := []*repository.PushCommit{
{
Sha1: "1a8823cd1a9549fde083f992f6b9b87a7ab74fb3",
CommitterEmail: "[email protected]",
CommitterName: "User Two",
AuthorEmail: "[email protected]",
AuthorName: "User Two",
Message: "Merge pull request 'issue2' (#2) from branch1 into master",
},
}
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
selfRefCommentBean := &issues_model.Comment{
Type: issues_model.CommentTypeCommitRef,
CommitSHA: "1a8823cd1a9549fde083f992f6b9b87a7ab74fb3",
PosterID: user.ID,
IssueID: 2,
}
unittest.AssertNotExistsBean(t, selfRefCommentBean)
assert.NoError(t, UpdateIssuesCommit(t.Context(), user, repo, pushCommits, repo.DefaultBranch))
unittest.AssertNotExistsBean(t, selfRefCommentBean)
unittest.CheckConsistencyFor(t, &activities_model.Action{})
// Test that normal commit references are still created
pushCommits2 := []*repository.PushCommit{
{
Sha1: "abcdef9876543210",
CommitterEmail: "[email protected]",
CommitterName: "User Two",
AuthorEmail: "[email protected]",
AuthorName: "User Two",
Message: "Fix bug, refs #1",
},
}
otherRefCommentBean := &issues_model.Comment{
Type: issues_model.CommentTypeCommitRef,
CommitSHA: "abcdef9876543210",
PosterID: user.ID,
IssueID: 1,
}
unittest.AssertNotExistsBean(t, otherRefCommentBean)
assert.NoError(t, UpdateIssuesCommit(t.Context(), user, repo, pushCommits2, repo.DefaultBranch))
unittest.AssertExistsAndLoadBean(t, otherRefCommentBean)
unittest.CheckConsistencyFor(t, &activities_model.Action{})
}