mirror of
https://github.com/go-gitea/gitea.git
synced 2026-07-10 03:10:00 +00:00
The commit page built its "co-authored by" list from `AllParticipantIdentities()[1:]`, which only drops the author and leaves the committer in the list even though the committer is already shown separately as "committed by". This caused the committer to be wrongly rendered as a co-author (issue #38384): a commit authored by `silverwind`, committed by `bircni`, with a `Co-authored-by: silverwind` trailer displayed "co-authored by bircni" instead of the actual trailer identity. This adds a `Commit.CoAuthorIdentities()` method that excludes both the author and the committer, uses it on the commit page, and covers the fix with a regression test. Closes #38384
122 lines
3.7 KiB
Go
122 lines
3.7 KiB
Go
// Copyright 2026 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package git
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func TestCommitMessageSanitizesInvalidUTF8(t *testing.T) {
|
|
commit := &Commit{
|
|
CommitMessage: CommitMessage{MessageRaw: "title \xff\n\n\n\nbody \xff\n\n\n"},
|
|
}
|
|
assert.Equal(t, "title ÿ", commit.MessageTitle())
|
|
assert.Equal(t, "body ÿ", commit.MessageBody())
|
|
assert.Equal(t, "title ÿ\n\n\n\nbody ÿ\n\n\n", commit.MessageUTF8())
|
|
}
|
|
|
|
func TestCommitMessageTrailer(t *testing.T) {
|
|
cases := []struct {
|
|
msg, body, sep, trailer string
|
|
}{
|
|
{"", "", "", ""},
|
|
{"a", "a", "", ""},
|
|
{"a\n\nk", "a\n\nk", "", ""},
|
|
{"a\n\nk:v", "a", "\n\n", "k:v"},
|
|
{"a\n\nk:v\n\n", "a", "\n\n", "k:v\n\n"},
|
|
{"a\n--\nk:v", "a\n--\nk:v", "", ""},
|
|
{"a\n---\nk:v", "a", "\n---\n", "k:v"},
|
|
{"a\n\n---\n\nk:v", "a\n", "\n---\n\n", "k:v"},
|
|
|
|
{"k: v", "", "", "k: v"},
|
|
{"\nk:v", "", "\n", "k:v"},
|
|
{"\n\nk:v", "", "\n\n", "k:v"},
|
|
|
|
{"---\nk:v", "", "---\n", "k:v"},
|
|
{"\n---\nk:v", "", "\n---\n", "k:v"},
|
|
{"a:b\n---\nk:v", "a:b", "\n---\n", "k:v"},
|
|
}
|
|
for _, c := range cases {
|
|
body, sep, trailer := CommitMessageSplitTrailer(c.msg)
|
|
assert.Equal(t, c.body, body, "input=%q", c.msg)
|
|
assert.Equal(t, c.sep, sep, "input=%q", c.msg)
|
|
assert.Equal(t, c.trailer, trailer, "input=%q", c.msg)
|
|
}
|
|
}
|
|
|
|
func TestCommitMessageAllParticipantIdentities(t *testing.T) {
|
|
sig := func(n, e string) *Signature { return &Signature{Name: n, Email: e} }
|
|
idt := func(n, e string) *CommitIdentity { return &CommitIdentity{Name: n, Email: e} }
|
|
cases := []struct {
|
|
commit *Commit
|
|
participant []*CommitIdentity
|
|
}{
|
|
{
|
|
&Commit{
|
|
Author: sig("a", "a@m.com"), Committer: sig("c", "c@m.com"),
|
|
CommitMessage: CommitMessage{MessageRaw: "CO-Authored-BY: x@m.com"},
|
|
},
|
|
[]*CommitIdentity{idt("a", "a@m.com"), idt("c", "c@m.com"), idt("", "x@m.com")},
|
|
},
|
|
{
|
|
&Commit{
|
|
Author: sig("a", "a@m.com"), Committer: sig("a", "A@M.com"),
|
|
CommitMessage: CommitMessage{MessageRaw: "CO-Authored-BY: a@m.com"},
|
|
},
|
|
[]*CommitIdentity{idt("a", "a@m.com")},
|
|
},
|
|
{
|
|
&Commit{
|
|
Author: sig("a", "a@m.com"), Committer: sig("", ""),
|
|
CommitMessage: CommitMessage{MessageRaw: "Co-authored-by: Full Name <X@M.com>"},
|
|
},
|
|
[]*CommitIdentity{idt("a", "a@m.com"), idt("Full Name", "X@M.com")},
|
|
},
|
|
}
|
|
for _, c := range cases {
|
|
assert.Equal(t, c.participant, c.commit.AllParticipantIdentities())
|
|
}
|
|
}
|
|
|
|
func TestCommitMessageCoAuthorIdentities(t *testing.T) {
|
|
sig := func(n, e string) *Signature { return &Signature{Name: n, Email: e} }
|
|
idt := func(n, e string) *CommitIdentity { return &CommitIdentity{Name: n, Email: e} }
|
|
cases := []struct {
|
|
commit *Commit
|
|
coAuthors []*CommitIdentity
|
|
}{
|
|
{
|
|
// a genuine co-author (neither author nor committer) is reported
|
|
&Commit{
|
|
Author: sig("a", "a@m.com"), Committer: sig("c", "c@m.com"),
|
|
CommitMessage: CommitMessage{MessageRaw: "Co-authored-by: x <x@m.com>"},
|
|
},
|
|
[]*CommitIdentity{idt("x", "x@m.com")},
|
|
},
|
|
{
|
|
// the committer is shown separately as "committed by", so it must
|
|
// not appear as a co-author even though it is a participant
|
|
&Commit{
|
|
Author: sig("a", "a@m.com"), Committer: sig("c", "c@m.com"),
|
|
CommitMessage: CommitMessage{MessageRaw: "Co-authored-by: c <c@m.com>"},
|
|
},
|
|
nil,
|
|
},
|
|
{
|
|
// regression for #38384: a Co-authored-by trailer naming the author
|
|
// must not cause the committer to be surfaced as the co-author
|
|
&Commit{
|
|
Author: sig("silverwind", "me@silverwind.io"), Committer: sig("bircni", "bircni@icloud.com"),
|
|
CommitMessage: CommitMessage{MessageRaw: "Co-authored-by: silverwind <me@silverwind.io>"},
|
|
},
|
|
nil,
|
|
},
|
|
}
|
|
for _, c := range cases {
|
|
assert.Equal(t, c.coAuthors, c.commit.CoAuthorIdentities())
|
|
}
|
|
}
|