···16181618issues.ref_reopened_from = `<a href="%[3]s">reopened this issue %[4]s</a> <a id="%[1]s" href="#%[1]s">%[2]s</a>`
16191619issues.ref_from = `from %[1]s`
16201620issues.author = Author
16211621-issues.author_helper = This user is the author.
16211621+issues.author.tooltip.issue = This user is the author of this issue.
16221622+issues.author.tooltip.pr = This user is the author of this pull request.
16221623issues.role.owner = Owner
16231624issues.role.owner_helper = This user is the owner of this repository.
16241625issues.role.member = Member
+1
release-notes/8.0.0/4201.md
···11+Make tooltip of Author label in comments more clear
···11+// Copyright 2024 The Forgejo Authors. All rights reserved.
22+// SPDX-License-Identifier: MIT
33+44+package integration
55+66+import (
77+ "net/http"
88+ "net/url"
99+ "path"
1010+ "strings"
1111+ "testing"
1212+1313+ "github.com/PuerkitoBio/goquery"
1414+ "github.com/stretchr/testify/assert"
1515+)
1616+1717+// TestIssuesCommentLabels is a test for user (role) labels in comment headers in PRs and issues.
1818+// It covers a few labels and combinations.
1919+func TestIssuesCommentLabels(t *testing.T) {
2020+ onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
2121+ user := "user2"
2222+ repo := "repo1"
2323+ compareLink := path.Join(user, repo, "compare", "master...comment-labels")
2424+ sessionUser1 := loginUser(t, "user1")
2525+ sessionUser2 := loginUser(t, "user2")
2626+ sessionUser5 := loginUser(t, "user5")
2727+2828+ ownerTooltip := "This user is the owner of this repository."
2929+ authorTooltipPR := "This user is the author of this pull request."
3030+ authorTooltipIssue := "This user is the author of this issue."
3131+ firstTooltip := "This is the first contribution of this user to the repository."
3232+3333+ // Open a new PR as user2
3434+ testEditFileToNewBranch(t, sessionUser2, user, repo, "master", "comment-labels", "README.md", "test of comment labels")
3535+ sessionUser2.MakeRequest(t, NewRequestWithValues(t, "POST", compareLink,
3636+ map[string]string{
3737+ "_csrf": GetCSRF(t, sessionUser2, compareLink),
3838+ "title": "Pull used for testing commit labels",
3939+ },
4040+ ), http.StatusOK)
4141+4242+ // Pull number, expected to be 6
4343+ testID := "6"
4444+ // Add a few comments
4545+ // (first: Owner)
4646+ testEasyLeavePRComment(t, sessionUser2, user, repo, testID, "New comment from user2 on this PR") // Author, Owner
4747+ testEasyLeavePRComment(t, sessionUser1, user, repo, testID, "New comment from user1 on this PR") // First-time contributor
4848+ testEasyLeavePRComment(t, sessionUser5, user, repo, testID, "New comment from user5 on this PR") // no labels
4949+5050+ // Fetch the PR page
5151+ response := sessionUser2.MakeRequest(t, NewRequest(t, "GET", path.Join(user, repo, "pulls", testID)), http.StatusOK)
5252+ page := NewHTMLParser(t, response.Body)
5353+ commentHeads := page.Find(".timeline .comment .comment-header .comment-header-right")
5454+ assert.EqualValues(t, 4, commentHeads.Length())
5555+5656+ // Test the first comment and it's label "Owner"
5757+ labels := commentHeads.Eq(0).Find(".role-label")
5858+ assert.EqualValues(t, 1, labels.Length())
5959+ testIssueCommentUserLabel(t, labels.Eq(0), "Owner", ownerTooltip)
6060+6161+ // Test the second comment and it's labels "Author" and "Owner"
6262+ labels = commentHeads.Eq(1).Find(".role-label")
6363+ assert.EqualValues(t, 2, labels.Length())
6464+ testIssueCommentUserLabel(t, labels.Eq(0), "Author", authorTooltipPR)
6565+ testIssueCommentUserLabel(t, labels.Eq(1), "Owner", ownerTooltip)
6666+6767+ // Test the third comment and it's label "First-time contributor"
6868+ labels = commentHeads.Eq(3).Find(".role-label")
6969+ assert.EqualValues(t, 1, labels.Length())
7070+ testIssueCommentUserLabel(t, labels.Eq(0), "First-time contributor", firstTooltip)
7171+7272+ // Test the fourth comment and it's lack of labels
7373+ labels = commentHeads.Eq(4).Find(".role-label")
7474+ assert.EqualValues(t, 0, labels.Length())
7575+7676+ // Open a new issue in the same repo
7777+ sessionUser2.MakeRequest(t, NewRequestWithValues(t, "POST", path.Join(user, repo, "issues/new"),
7878+ map[string]string{
7979+ "_csrf": GetCSRF(t, sessionUser2, compareLink),
8080+ "title": "Issue used for testing commit labels",
8181+ },
8282+ ), http.StatusOK)
8383+8484+ // Issue number, expected to be 7 after the PR
8585+ testID = "7"
8686+ // Add a few comments
8787+ // (first: Owner)
8888+ testEasyLeaveIssueComment(t, sessionUser2, user, repo, testID, "New comment from user2 on this issue") // Author, Owner
8989+ testEasyLeaveIssueComment(t, sessionUser5, user, repo, testID, "New comment from user5 on this issue") // no labels
9090+9191+ // Fetch the issue page
9292+ response = sessionUser2.MakeRequest(t, NewRequest(t, "GET", path.Join(user, repo, "issues", testID)), http.StatusOK)
9393+ page = NewHTMLParser(t, response.Body)
9494+ commentHeads = page.Find(".timeline .comment .comment-header .comment-header-right")
9595+ assert.EqualValues(t, 3, commentHeads.Length())
9696+9797+ // Test the first comment and it's label "Owner"
9898+ labels = commentHeads.Eq(0).Find(".role-label")
9999+ assert.EqualValues(t, 1, labels.Length())
100100+ testIssueCommentUserLabel(t, labels.Eq(0), "Owner", ownerTooltip)
101101+102102+ // Test the second comment and it's labels "Author" and "Owner"
103103+ labels = commentHeads.Eq(1).Find(".role-label")
104104+ assert.EqualValues(t, 2, labels.Length())
105105+ testIssueCommentUserLabel(t, labels.Eq(0), "Author", authorTooltipIssue)
106106+ testIssueCommentUserLabel(t, labels.Eq(1), "Owner", ownerTooltip)
107107+108108+ // Test the third comment and it's lack of labels
109109+ labels = commentHeads.Eq(3).Find(".role-label")
110110+ assert.EqualValues(t, 0, labels.Length())
111111+ })
112112+}
113113+114114+// testIssueCommentUserLabel is used to verify properties of a user label from a comment
115115+func testIssueCommentUserLabel(t *testing.T, label *goquery.Selection, expectedTitle, expectedTooltip string) {
116116+ t.Helper()
117117+ title := label.Text()
118118+ tooltip, exists := label.Attr("data-tooltip-content")
119119+ assert.True(t, exists)
120120+ assert.EqualValues(t, expectedTitle, strings.TrimSpace(title))
121121+ assert.EqualValues(t, expectedTooltip, strings.TrimSpace(tooltip))
122122+}
123123+124124+// testEasyLeaveIssueComment is used to create a comment on an issue with minimum code and parameters
125125+func testEasyLeaveIssueComment(t *testing.T, session *TestSession, user, repo, id, message string) {
126126+ t.Helper()
127127+ session.MakeRequest(t, NewRequestWithValues(t, "POST", path.Join(user, repo, "issues", id, "comments"), map[string]string{
128128+ "_csrf": GetCSRF(t, session, path.Join(user, repo, "issues", id)),
129129+ "content": message,
130130+ "status": "",
131131+ }), 200)
132132+}
133133+134134+// testEasyLeaveIssueComment is used to create a comment on a pull request with minimum code and parameters
135135+// The POST request is supposed to use "issues" in the path. The CSRF is supposed to be generated for the PR page.
136136+func testEasyLeavePRComment(t *testing.T, session *TestSession, user, repo, id, message string) {
137137+ t.Helper()
138138+ session.MakeRequest(t, NewRequestWithValues(t, "POST", path.Join(user, repo, "issues", id, "comments"), map[string]string{
139139+ "_csrf": GetCSRF(t, session, path.Join(user, repo, "pulls", id)),
140140+ "content": message,
141141+ "status": "",
142142+ }), 200)
143143+}