fix: Allow SHA-256 in PR commit URLs (#10309)

Closes #9129. I decided to try myself in contributing to Forgejo after having found this bug mentioned on Fedi.

I have also added a basic test for this behaviour, but this means that this PR adds a SHA-256 repo to the fixture set, so it can be reused in other tests.

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10309
Reviewed-by: Lucas <sclu1034@noreply.codeberg.org>
Reviewed-by: 0ko <0ko@noreply.codeberg.org>
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: Nikita Karamov <me@kytta.dev>
Co-committed-by: Nikita Karamov <me@kytta.dev>
This commit is contained in:
Nikita Karamov 2025-12-16 00:45:00 +01:00 committed by Gusted
parent 0398fa85e1
commit a22e5f86c6
46 changed files with 260 additions and 32 deletions

View file

@ -69,3 +69,25 @@
is_deleted: false
deleted_by_id: 0
deleted_unix: 0
- id: 17
repo_id: 66
name: 'master'
commit_id: '7b299a0be8450b8304e30f1f7feea2383903e02bb4b7600d37eb2bb6e934daba'
commit_message: 'Initial commit'
commit_time: 1764879244
pusher_id: 2
is_deleted: false
deleted_by_id: 0
deleted_unix: 0
- id: 18
repo_id: 66
name: 'branch2'
commit_id: '004581b3bb63754502364664021404490ee747ce58e98d27c046f2e46f5f2f55'
commit_message: 'PR'
commit_time: 1764879438
pusher_id: 2
is_deleted: false
deleted_by_id: 0
deleted_unix: 0

View file

@ -372,3 +372,19 @@
created_unix: 1707270422
updated_unix: 1707270422
is_locked: false
- id: 24
repo_id: 66
index: 1
poster_id: 2
original_author_id: 0
name: PR
content: ''
milestone_id: 0
priority: 0
is_closed: false
is_pull: true
num_comments: 0
created_unix: 1764879458
updated_unix: 1764879458
is_locked: false

View file

@ -25,3 +25,6 @@
-
group_id: 51
max_index: 1
- group_id: 66
max_index: 1

View file

@ -119,3 +119,16 @@
index: 1
head_repo_id: 61
base_repo_id: 61
- id: 12
type: 0 # gitea pull request
status: 2 # mergeable
issue_id: 24
index: 1
head_repo_id: 66
base_repo_id: 66
head_branch: branch2
base_branch: master
merge_base: 004581b3bb63754502364664021404490ee747ce58e98d27c046f2e46f5f2f55
has_merged: false

View file

@ -802,3 +802,34 @@
type: 10
config: "{}"
created_unix: 946684810
-
id: 116
repo_id: 66
type: 1
config: "{}"
created_unix: 1764879302
- id: 117
repo_id: 66
type: 2
config: "{\"EnableTimetracker\":true,\"AllowOnlyContributorsToTrackTime\":true,\"EnableDependencies\":true}"
created_unix: 1764879302
- id: 118
repo_id: 66
type: 3
config: "{\"IgnoreWhitespaceConflicts\":false,\"AllowMerge\":true,\"AllowRebase\":true,\"AllowRebaseMerge\":true,\"AllowSquash\":true}"
created_unix: 1764879302
- id: 119
repo_id: 66
type: 4
config: "{}"
created_unix: 1764879302
- id: 120
repo_id: 66
type: 5
config: "{}"
created_unix: 1764879302

View file

@ -1684,3 +1684,34 @@
is_fsck_enabled: true
close_issues_via_commit_in_any_branch: false
topics: '[]'
-
id: 66
owner_id: 2
owner_name: user2
lower_name: repo256
name: repo256
default_branch: master
num_watches: 0
num_stars: 0
num_forks: 0
num_milestones: 0
num_closed_milestones: 0
num_projects: 0
num_closed_projects: 0
is_private: false
is_empty: false
is_archived: false
is_mirror: false
status: 0
is_fork: false
fork_id: 0
is_template: false
template_id: 0
size: 24586
is_fsck_enabled: true
close_issues_via_commit_in_any_branch: false
created_unix: 1764879302
updated_unix: 1764879302
topics: '[]'
object_format_name: 'sha256'

View file

@ -70,7 +70,7 @@
num_followers: 2
num_following: 1
num_stars: 2
num_repos: 18
num_repos: 19
num_teams: 0
num_members: 0
visibility: 0

View file

@ -431,7 +431,7 @@ func TestCountIssues(t *testing.T) {
require.NoError(t, unittest.PrepareTestDatabase())
count, err := issues_model.CountIssues(db.DefaultContext, &issues_model.IssuesOptions{})
require.NoError(t, err)
assert.EqualValues(t, 22, count)
assert.EqualValues(t, 23, count)
}
func TestIssueLoadAttributes(t *testing.T) {

View file

@ -142,12 +142,12 @@ func getTestCases() []struct {
{
name: "AllPublic/PublicRepositoriesOfUserIncludingCollaborative",
opts: &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 15, AllPublic: true, Template: optional.Some(false)},
count: 35,
count: 36,
},
{
name: "AllPublic/PublicAndPrivateRepositoriesOfUserIncludingCollaborative",
opts: &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 15, Private: true, AllPublic: true, AllLimited: true, Template: optional.Some(false)},
count: 40,
count: 41,
},
{
name: "AllPublic/PublicAndPrivateRepositoriesOfUserIncludingCollaborativeByName",
@ -162,7 +162,7 @@ func getTestCases() []struct {
{
name: "AllPublic/PublicRepositoriesOfOrganization",
opts: &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 17, AllPublic: true, Collaborate: optional.Some(false), Template: optional.Some(false)},
count: 35,
count: 36,
},
{
name: "AllTemplates",
@ -172,7 +172,7 @@ func getTestCases() []struct {
{
name: "OwnerSlashRepoSearch",
opts: &repo_model.SearchRepoOptions{Keyword: "user/repo2", ListOptions: db.ListOptions{Page: 1, PageSize: 10}, Private: true, OwnerID: 0},
count: 2,
count: 3,
},
{
name: "OwnerSlashSearch",
@ -420,15 +420,15 @@ func TestSearchRepositoryIDsByCondition(t *testing.T) {
}{
{
user: nil,
repoIDs: []int64{1, 4, 8, 9, 10, 11, 12, 14, 17, 18, 21, 23, 25, 27, 29, 32, 33, 34, 35, 36, 37, 42, 44, 45, 46, 47, 48, 49, 50, 51, 53, 57, 58, 60, 61, 62, 1059},
repoIDs: []int64{1, 4, 8, 9, 10, 11, 12, 14, 17, 18, 21, 23, 25, 27, 29, 32, 33, 34, 35, 36, 37, 42, 44, 45, 46, 47, 48, 49, 50, 51, 53, 57, 58, 60, 61, 62, 66, 1059},
},
{
user: unittest.AssertExistsAndLoadBean(t, &user.User{ID: 4}),
repoIDs: []int64{1, 3, 4, 8, 9, 10, 11, 12, 14, 17, 18, 21, 23, 25, 27, 29, 32, 33, 34, 35, 36, 37, 38, 40, 42, 44, 45, 46, 47, 48, 49, 50, 51, 53, 57, 58, 60, 61, 62, 1001, 1059},
repoIDs: []int64{1, 3, 4, 8, 9, 10, 11, 12, 14, 17, 18, 21, 23, 25, 27, 29, 32, 33, 34, 35, 36, 37, 38, 40, 42, 44, 45, 46, 47, 48, 49, 50, 51, 53, 57, 58, 60, 61, 62, 66, 1001, 1059},
},
{
user: unittest.AssertExistsAndLoadBean(t, &user.User{ID: 5}),
repoIDs: []int64{1, 4, 8, 9, 10, 11, 12, 14, 17, 18, 21, 23, 25, 27, 29, 32, 33, 34, 35, 36, 37, 38, 40, 42, 44, 45, 46, 47, 48, 49, 50, 51, 53, 57, 58, 60, 61, 62, 1001, 1059},
repoIDs: []int64{1, 4, 8, 9, 10, 11, 12, 14, 17, 18, 21, 23, 25, 27, 29, 32, 33, 34, 35, 36, 37, 38, 40, 42, 44, 45, 46, 47, 48, 49, 50, 51, 53, 57, 58, 60, 61, 62, 66, 1001, 1059},
},
}

View file

@ -157,7 +157,7 @@ func searchIssueByID(t *testing.T) {
{
// NOTE: This tests no assignees filtering and also ToSearchOptions() to ensure it will set AssigneeID to 0 when it is passed as -1.
opts: *ToSearchOptions(t.Context(), "", &issues.IssuesOptions{AssigneeID: -1}),
expectedIDs: []int64{22, 21, 16, 15, 14, 13, 12, 11, 20, 5, 19, 18, 10, 7, 4, 9, 8, 3, 2},
expectedIDs: []int64{24, 22, 21, 16, 15, 14, 13, 12, 11, 20, 5, 19, 18, 10, 7, 4, 9, 8, 3, 2},
},
{
opts: SearchOptions{
@ -222,7 +222,7 @@ func searchIssueIsPull(t *testing.T) {
SearchOptions{
IsPull: optional.Some(true),
},
[]int64{22, 21, 12, 11, 20, 19, 9, 8, 3, 2},
[]int64{24, 22, 21, 12, 11, 20, 19, 9, 8, 3, 2},
},
}
for _, test := range tests {
@ -242,7 +242,7 @@ func searchIssueIsClosed(t *testing.T) {
SearchOptions{
IsClosed: optional.Some(false),
},
[]int64{22, 21, 17, 16, 15, 14, 13, 12, 11, 20, 6, 19, 18, 10, 7, 9, 8, 3, 2, 1},
[]int64{24, 22, 21, 17, 16, 15, 14, 13, 12, 11, 20, 6, 19, 18, 10, 7, 9, 8, 3, 2, 1},
},
{
SearchOptions{
@ -305,7 +305,7 @@ func searchIssueByLabelID(t *testing.T) {
SearchOptions{
ExcludedLabelIDs: []int64{1},
},
[]int64{22, 21, 17, 16, 15, 14, 13, 12, 11, 20, 6, 5, 19, 18, 10, 7, 4, 9, 8, 3},
[]int64{24, 22, 21, 17, 16, 15, 14, 13, 12, 11, 20, 6, 5, 19, 18, 10, 7, 4, 9, 8, 3},
},
}
for _, test := range tests {
@ -325,7 +325,7 @@ func searchIssueByTime(t *testing.T) {
SearchOptions{
UpdatedAfterUnix: optional.Some(int64(0)),
},
[]int64{22, 21, 17, 16, 15, 14, 13, 12, 11, 20, 6, 5, 19, 18, 10, 7, 4, 9, 8, 3, 2, 1},
[]int64{24, 22, 21, 17, 16, 15, 14, 13, 12, 11, 20, 6, 5, 19, 18, 10, 7, 4, 9, 8, 3, 2, 1},
},
}
for _, test := range tests {
@ -345,7 +345,7 @@ func searchIssueWithOrder(t *testing.T) {
SearchOptions{
SortBy: internal.SortByCreatedAsc,
},
[]int64{1, 2, 3, 8, 9, 4, 7, 10, 18, 19, 5, 6, 20, 11, 12, 13, 14, 15, 16, 17, 21, 22},
[]int64{1, 2, 3, 8, 9, 4, 7, 10, 18, 19, 5, 6, 20, 11, 12, 13, 14, 15, 16, 17, 21, 22, 24},
},
}
for _, test := range tests {
@ -400,8 +400,8 @@ func searchIssueWithPaginator(t *testing.T) {
PageSize: 5,
},
},
[]int64{22, 21, 17, 16, 15},
22,
[]int64{24, 22, 21, 17, 16},
23,
},
}
for _, test := range tests {

View file

@ -78,7 +78,7 @@ func TestPulls(t *testing.T) {
Pulls(ctx)
assert.Equal(t, http.StatusOK, ctx.Resp.Status())
assert.Len(t, ctx.Data["Issues"], 5)
assert.Len(t, ctx.Data["Issues"], 6)
}
func TestMilestones(t *testing.T) {

View file

@ -1559,7 +1559,7 @@ func registerRoutes(m *web.Route) {
m.Group("/commits", func() {
m.Get("", context.RepoRef(), repo.SetWhitespaceBehavior, repo.GetPullDiffStats, repo.ViewPullCommits)
m.Get("/list", context.RepoRef(), repo.GetPullCommits)
m.Group("/{sha:[a-f0-9]{4,40}}", func() {
m.Group("/{sha:[a-f0-9]{4,64}}", func() {
m.Get("", context.RepoRef(), repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.SetShowOutdatedComments, repo.ViewPullFilesForSingleCommit)
m.Post("/reviews/submit", context.RepoMustNotBeArchived(), web.Bind(forms.SubmitReviewForm{}), repo.SubmitReview)
})
@ -1571,8 +1571,8 @@ func registerRoutes(m *web.Route) {
m.Post("/cleanup", context.RepoMustNotBeArchived(), context.RepoRef(), repo.CleanUpPullRequest)
m.Group("/files", func() {
m.Get("", context.RepoRef(), repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.SetShowOutdatedComments, repo.ViewPullFilesForAllCommitsOfPr)
m.Get("/{sha:[a-f0-9]{4,40}}", context.RepoRef(), repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.SetShowOutdatedComments, repo.ViewPullFilesStartingFromCommit)
m.Get("/{shaFrom:[a-f0-9]{4,40}}..{shaTo:[a-f0-9]{4,40}}", context.RepoRef(), repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.SetShowOutdatedComments, repo.ViewPullFilesForRange)
m.Get("/{sha:[a-f0-9]{4,64}}", context.RepoRef(), repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.SetShowOutdatedComments, repo.ViewPullFilesStartingFromCommit)
m.Get("/{shaFrom:[a-f0-9]{4,64}}..{shaTo:[a-f0-9]{4,64}}", context.RepoRef(), repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.SetShowOutdatedComments, repo.ViewPullFilesForRange)
m.Group("/reviews", func() {
m.Get("/new_comment", repo.RenderNewCodeCommentForm)
m.Post("/comments", web.Bind(forms.CodeCommentForm{}), repo.SetShowOutdatedComments, repo.CreateCodeComment)

View file

@ -0,0 +1 @@
004581b3bb63754502364664021404490ee747ce58e98d27c046f2e46f5f2f55 branch 'branch2' of file:///data/git/repositories/user2/repo256

View file

@ -0,0 +1 @@
ref: refs/heads/master

View file

@ -0,0 +1,7 @@
[extensions]
objectformat = sha256
[core]
repositoryformatversion = 1
filemode = true
bare = true
ignorecase = true

View file

@ -0,0 +1 @@
Unnamed repository; edit this file 'description' to name the repository.

View file

@ -0,0 +1,16 @@
#!/usr/bin/env bash
# AUTO GENERATED BY GITEA, DO NOT MODIFY
data=$(cat)
exitcodes=""
hookname=$(basename $0)
GIT_DIR=${GIT_DIR:-$(dirname $0)/..}
for hook in ${GIT_DIR}/hooks/${hookname}.d/*; do
test -x "${hook}" && test -f "${hook}" || continue
echo "${data}" | "${hook}"
exitcodes="${exitcodes} $?"
done
for i in ${exitcodes}; do
[ ${i} -eq 0 ] || exit ${i}
done

View file

@ -0,0 +1,3 @@
#!/usr/bin/env bash
# AUTO GENERATED BY GITEA, DO NOT MODIFY
/usr/local/bin/gitea hook --config=/data/gitea/conf/app.ini post-receive

View file

@ -0,0 +1,16 @@
#!/usr/bin/env bash
# AUTO GENERATED BY GITEA, DO NOT MODIFY
data=$(cat)
exitcodes=""
hookname=$(basename $0)
GIT_DIR=${GIT_DIR:-$(dirname $0)/..}
for hook in ${GIT_DIR}/hooks/${hookname}.d/*; do
test -x "${hook}" && test -f "${hook}" || continue
echo "${data}" | "${hook}"
exitcodes="${exitcodes} $?"
done
for i in ${exitcodes}; do
[ ${i} -eq 0 ] || exit ${i}
done

View file

@ -0,0 +1,3 @@
#!/usr/bin/env bash
# AUTO GENERATED BY GITEA, DO NOT MODIFY
/usr/local/bin/gitea hook --config=/data/gitea/conf/app.ini pre-receive

View file

@ -0,0 +1,3 @@
#!/usr/bin/env bash
# AUTO GENERATED BY GITEA, DO NOT MODIFY
/usr/local/bin/gitea hook --config=/data/gitea/conf/app.ini proc-receive

View file

@ -0,0 +1,15 @@
#!/usr/bin/env bash
# AUTO GENERATED BY GITEA, DO NOT MODIFY
exitcodes=""
hookname=$(basename $0)
GIT_DIR=${GIT_DIR:-$(dirname $0/..)}
for hook in ${GIT_DIR}/hooks/${hookname}.d/*; do
test -x "${hook}" && test -f "${hook}" || continue
"${hook}" $1 $2 $3
exitcodes="${exitcodes} $?"
done
for i in ${exitcodes}; do
[ ${i} -eq 0 ] || exit ${i}
done

View file

@ -0,0 +1,3 @@
#!/usr/bin/env bash
# AUTO GENERATED BY GITEA, DO NOT MODIFY
/usr/local/bin/gitea hook --config=/data/gitea/conf/app.ini update $1 $2 $3

View file

@ -0,0 +1,6 @@
# git ls-files --others --exclude-from=.git/info/exclude
# Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
# *.[oa]
# *~

View file

@ -0,0 +1,2 @@
004581b3bb63754502364664021404490ee747ce58e98d27c046f2e46f5f2f55 refs/heads/branch2
7b299a0be8450b8304e30f1f7feea2383903e02bb4b7600d37eb2bb6e934daba refs/heads/main

View file

@ -0,0 +1 @@
0000000000000000000000000000000000000000000000000000000000000000 7b299a0be8450b8304e30f1f7feea2383903e02bb4b7600d37eb2bb6e934daba Gitea <gitea@fake.local> 1764879318 +0000 push

View file

@ -0,0 +1 @@
0000000000000000000000000000000000000000000000000000000000000000 004581b3bb63754502364664021404490ee747ce58e98d27c046f2e46f5f2f55 Gitea <gitea@fake.local> 1764879445 +0000 push

View file

@ -0,0 +1 @@
0000000000000000000000000000000000000000000000000000000000000000 7b299a0be8450b8304e30f1f7feea2383903e02bb4b7600d37eb2bb6e934daba Gitea <gitea@fake.local> 1764879318 +0000 push

View file

@ -0,0 +1 @@
b89845831ab35606e6a2cdfb07ccc01e73da0717f8fec878cbc35d506f97f9f8

View file

@ -0,0 +1 @@
004581b3bb63754502364664021404490ee747ce58e98d27c046f2e46f5f2f55

View file

@ -0,0 +1 @@
7b299a0be8450b8304e30f1f7feea2383903e02bb4b7600d37eb2bb6e934daba

View file

@ -0,0 +1 @@
004581b3bb63754502364664021404490ee747ce58e98d27c046f2e46f5f2f55

View file

@ -491,7 +491,7 @@ func TestAPISearchIssues(t *testing.T) {
req = NewRequest(t, "GET", link.String()).AddTokenAuth(publicOnlyToken)
resp = MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &apiIssues)
assert.Len(t, apiIssues, 15) // 15 public issues
assert.Len(t, apiIssues, 16) // 16 public issues
since := "2000-01-01T00:50:01+00:00" // 946687801
before := time.Unix(999307200, 0).Format(time.RFC3339)
@ -517,7 +517,7 @@ func TestAPISearchIssues(t *testing.T) {
req = NewRequest(t, "GET", link.String()).AddTokenAuth(token)
resp = MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &apiIssues)
assert.Equal(t, "22", resp.Header().Get("X-Total-Count"))
assert.Equal(t, "23", resp.Header().Get("X-Total-Count"))
assert.Len(t, apiIssues, 20)
query.Add("limit", "10")
@ -525,7 +525,7 @@ func TestAPISearchIssues(t *testing.T) {
req = NewRequest(t, "GET", link.String()).AddTokenAuth(token)
resp = MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &apiIssues)
assert.Equal(t, "22", resp.Header().Get("X-Total-Count"))
assert.Equal(t, "23", resp.Header().Get("X-Total-Count"))
assert.Len(t, apiIssues, 10)
query = url.Values{"assigned": {"true"}, "state": {"all"}}
@ -554,7 +554,7 @@ func TestAPISearchIssues(t *testing.T) {
req = NewRequest(t, "GET", link.String()).AddTokenAuth(token)
resp = MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &apiIssues)
assert.Len(t, apiIssues, 8)
assert.Len(t, apiIssues, 9)
query = url.Values{"owner": {"org3"}} // organization
link.RawQuery = query.Encode()

View file

@ -30,6 +30,6 @@ func TestNodeinfo(t *testing.T) {
assert.True(t, nodeinfo.OpenRegistrations)
assert.Equal(t, "forgejo", nodeinfo.Software.Name)
assert.Equal(t, 29, nodeinfo.Usage.Users.Total)
assert.Equal(t, 22, nodeinfo.Usage.LocalPosts)
assert.Equal(t, 23, nodeinfo.Usage.LocalPosts)
assert.Equal(t, 4, nodeinfo.Usage.LocalComments)
}

View file

@ -96,9 +96,9 @@ func TestAPISearchRepo(t *testing.T) {
}{
{
name: "RepositoriesMax50", requestURL: "/api/v1/repos/search?limit=50&private=false", expectedResults: expectedResults{
nil: {count: 37},
user: {count: 37},
user2: {count: 37},
nil: {count: 38},
user: {count: 38},
user2: {count: 38},
},
},
{

View file

@ -899,7 +899,7 @@ func TestSearchIssues(t *testing.T) {
req = NewRequest(t, "GET", link.String())
resp = session.MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &apiIssues)
assert.Equal(t, "22", resp.Header().Get("X-Total-Count"))
assert.Equal(t, "23", resp.Header().Get("X-Total-Count"))
assert.Len(t, apiIssues, 20)
query.Add("limit", "5")
@ -907,7 +907,7 @@ func TestSearchIssues(t *testing.T) {
req = NewRequest(t, "GET", link.String())
resp = session.MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &apiIssues)
assert.Equal(t, "22", resp.Header().Get("X-Total-Count"))
assert.Equal(t, "23", resp.Header().Get("X-Total-Count"))
assert.Len(t, apiIssues, 5)
query = url.Values{"assigned": {"true"}, "state": {"all"}}
@ -936,7 +936,7 @@ func TestSearchIssues(t *testing.T) {
req = NewRequest(t, "GET", link.String())
resp = session.MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &apiIssues)
assert.Len(t, apiIssues, 8)
assert.Len(t, apiIssues, 9)
query = url.Values{"owner": {"org3"}} // organization
link.RawQuery = query.Encode()

View file

@ -62,6 +62,33 @@ func TestPullCommitLinks(t *testing.T) {
assert.Equal(t, "/user2/repo1/pulls/3/commits/5f22f7d0d95d614d25a5b68592adb345a4b5c7fd", commitLinkHref)
}
func TestPullCommitLinksSHA256(t *testing.T) {
if !git.SupportHashSha256 {
t.Skip("skipping because installed Git version doesn't support SHA256")
return
}
defer tests.PrepareTestEnv(t)()
req := NewRequest(t, "GET", "/user2/repo256/pulls/1/commits")
resp := MakeRequest(t, req, http.StatusOK)
htmlDoc := NewHTMLParser(t, resp.Body)
commitSha := htmlDoc.Find(".commit-list td.sha a.sha.label").First()
commitShaHref, commitShaOk := commitSha.Attr("href")
assert.True(t, commitShaOk)
assert.Equal(t, "/user2/repo256/pulls/1/commits/004581b3bb63754502364664021404490ee747ce58e98d27c046f2e46f5f2f55", commitShaHref)
commitLink := htmlDoc.Find(".commit-list td.message a").First()
commitLinkHref, commitLinkOk := commitLink.Attr("href")
assert.True(t, commitLinkOk)
assert.Equal(t, "/user2/repo256/pulls/1/commits/004581b3bb63754502364664021404490ee747ce58e98d27c046f2e46f5f2f55", commitLinkHref)
commitReq := NewRequest(t, "GET", commitShaHref)
MakeRequest(t, commitReq, http.StatusOK)
}
func TestPullCommitSignature(t *testing.T) {
t.Cleanup(func() {
// Cannot use t.Context(), it is in the done state.