diff --git a/modules/templates/helper.go b/modules/templates/helper.go index 55de85646c..9d4434f7b0 100644 --- a/modules/templates/helper.go +++ b/modules/templates/helper.go @@ -6,6 +6,8 @@ package templates import ( + "bytes" + "context" "fmt" "html" "html/template" @@ -29,6 +31,23 @@ func NewFuncMap() template.FuncMap { return map[string]any{ "ctx": func() any { return nil }, // template context function + "ExecuteTemplate": func(ctx context.Context, tmplName string, args any) template.HTML { + h := HTMLRenderer() + tmpl, err := h.TemplateLookup(tmplName, ctx) + if err != nil { + panic("Template not found: " + tmplName) + } + + buf := bytes.Buffer{} + if err := tmpl.Execute(&buf, args); err != nil { + panic("Error while executing template") + } + + // We can safely return this as `template.HTML` as html/template will + // already make sure it's sanitized. + return template.HTML(buf.String()) + }, + "DumpVar": dumpVar, // ----------------------------------------------------------------- diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index f836d8fb57..d08c4cdaa3 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -1746,8 +1746,8 @@ issues.add_time_sum_to_small = No time was entered. issues.time_spent_total = Total time spent issues.time_spent_from_all_authors = `Total time spent: %s` issues.due_date = Due date -issues.push_commit_1 = added %d commit %s -issues.push_commits_n = added %d commits %s +discussion.added_commits_one = %[1]s added %[2]d commit %[3]s +discussion.added_commits_few = %[1]s added %[2]d commits %[3]s issues.force_push_codes = `force-pushed %[1]s from %[2]s to %[4]s %[6]s` issues.force_push_compare = Compare issues.due_date_form = yyyy-mm-dd diff --git a/templates/repo/issue/view_content/comments.tmpl b/templates/repo/issue/view_content/comments.tmpl index c8eabb9345..1d45b79d0d 100644 --- a/templates/repo/issue/view_content/comments.tmpl +++ b/templates/repo/issue/view_content/comments.tmpl @@ -549,11 +549,10 @@
{{svg "octicon-repo-push"}} - {{template "shared/user/authorlink" .Poster}} {{if .IsForcePush}} - {{ctx.Locale.Tr "repo.issues.force_push_codes" $.Issue.PullRequest.HeadBranch (ShortSha .OldCommit) ($.Issue.Repo.CommitLink .OldCommit) (ShortSha .NewCommit) ($.Issue.Repo.CommitLink .NewCommit) $createdStr "ui sha"}} + {{template "shared/user/authorlink" .Poster}} {{ctx.Locale.Tr "repo.issues.force_push_codes" $.Issue.PullRequest.HeadBranch (ShortSha .OldCommit) ($.Issue.Repo.CommitLink .OldCommit) (ShortSha .NewCommit) ($.Issue.Repo.CommitLink .NewCommit) $createdStr "ui sha"}} {{else}} - {{ctx.Locale.TrN (len .Commits) "repo.issues.push_commit_1" "repo.issues.push_commits_n" (len .Commits) $createdStr}} + {{ctx.Locale.TrN (len .Commits) "repo.discussion.added_commits_one" "repo.discussion.added_commits_few" (ExecuteTemplate ctx "shared/user/authorlink" .Poster) (len .Commits) $createdStr}} {{end}} {{if and .IsForcePush $.Issue.PullRequest.BaseRepo.Name}} diff --git a/tests/integration/discussion_events_test.go b/tests/integration/discussion_events_test.go new file mode 100644 index 0000000000..4c63f56580 --- /dev/null +++ b/tests/integration/discussion_events_test.go @@ -0,0 +1,72 @@ +// Copyright 2024 The Forgejo Authors. All rights reserved. +// SPDX-License-Identifier: GPL-3.0-or-later + +package integration + +import ( + "fmt" + "net/http" + "net/url" + "path" + "regexp" + "strings" + "testing" + + auth_model "code.gitea.io/gitea/models/auth" + api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/tests" + + "github.com/stretchr/testify/assert" +) + +// TestDiscussionEvents is a test for various events displayed in the timelines of pulls and issues +func TestDiscussionEvents(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + repoName := "discussion-timeline-tests" + user1 := "user1" + description := "This PR will be used for testing events in discussions" + // Expected branch name when initializing repo automatically + defaultBranch := "master" + htmlCleaner := regexp.MustCompile(`[\t\n]`) + + onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) { + sessionUser1 := loginUser(t, user1) + tokenUser1 := getTokenForLoggedInUser(t, sessionUser1, auth_model.AccessTokenScopeAll) + + // Create test repo + var repo api.Repository + resp := sessionUser1.MakeRequest(t, NewRequestWithJSON(t, "POST", "/api/v1/user/repos", &api.CreateRepoOption{ + Name: repoName, + AutoInit: true, + }).AddTokenAuth(tokenUser1), http.StatusCreated) + DecodeJSON(t, resp, &repo) + + // == Test pulls == + + // Open a new PR as user1 + testEditFileToNewBranch(t, sessionUser1, user1, repo.Name, defaultBranch, "comment-labels", "README.md", description) + sessionUser1.MakeRequest(t, NewRequestWithValues(t, "POST", path.Join(repo.FullName, "compare", fmt.Sprintf("%s...comment-labels", defaultBranch)), + map[string]string{ + "_csrf": GetCSRF(t, sessionUser1, path.Join(repo.FullName, "compare", fmt.Sprintf("%s...comment-labels", defaultBranch))), + "title": description, + }, + ), http.StatusOK) + + // Pull number, expected to be 1 in a fresh repo + testPullID := "1" + + // Get the PR page and find all events + response := sessionUser1.MakeRequest(t, NewRequest(t, "GET", path.Join(repo.FullName, "pulls", testPullID)), http.StatusOK) + page := NewHTMLParser(t, response.Body) + events := page.Find(".timeline .timeline-item.event .text") + + // Check the event. Should contain: " added 1 commit " + event := events.Eq(0) + eventHTML, _ := event.Html() + eventText := htmlCleaner.ReplaceAllString(strings.TrimSpace(event.Text()), "") + assert.Contains(t, eventHTML, `href="/user1">user1`) + assert.Contains(t, eventHTML, `