From 3fab07e0bc8e5bb80d72c09785b10a38c7073fbe Mon Sep 17 00:00:00 2001
From: Chl <chl@xlii.si>
Date: Thu, 15 Aug 2024 21:28:49 +0200
Subject: [PATCH 1/2] follow up on #2367: rel="nofollow" on in-list labels

The forgejo/forgejo#2367 pull requests added rel="nofollow" on filters in the
menu, this commit adds it on the labels in the listing and a few other places.
---
 modules/templates/util_render.go       | 2 +-
 templates/repo/issue/labels/label.tmpl | 1 +
 templates/shared/issuelist.tmpl        | 2 +-
 3 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/modules/templates/util_render.go b/modules/templates/util_render.go
index c4c5376afd..76790b63d5 100644
--- a/modules/templates/util_render.go
+++ b/modules/templates/util_render.go
@@ -245,7 +245,7 @@ func RenderLabels(ctx context.Context, locale translation.Locale, labels []*issu
 		if isPull {
 			issuesOrPull = "pulls"
 		}
-		htmlCode += fmt.Sprintf("<a href='%s/%s?labels=%d'>%s</a> ",
+		htmlCode += fmt.Sprintf("<a href='%s/%s?labels=%d' rel='nofollow'>%s</a> ",
 			repoLink, issuesOrPull, label.ID, RenderLabel(ctx, locale, label))
 	}
 	htmlCode += "</span>"
diff --git a/templates/repo/issue/labels/label.tmpl b/templates/repo/issue/labels/label.tmpl
index 3651ba118f..7844362911 100644
--- a/templates/repo/issue/labels/label.tmpl
+++ b/templates/repo/issue/labels/label.tmpl
@@ -2,6 +2,7 @@
 	class="item {{if not .label.IsChecked}}tw-hidden{{end}}"
 	id="label_{{.label.ID}}"
 	href="{{.root.RepoLink}}/{{if or .root.IsPull .root.Issue.IsPull}}pulls{{else}}issues{{end}}?labels={{.label.ID}}"{{/* FIXME: use .root.Issue.Link or create .root.Link */}}
+	rel="nofollow"
 >
 	{{- RenderLabel $.Context ctx.Locale .label -}}
 </a>
diff --git a/templates/shared/issuelist.tmpl b/templates/shared/issuelist.tmpl
index 78bfca1c63..f96c1828d2 100644
--- a/templates/shared/issuelist.tmpl
+++ b/templates/shared/issuelist.tmpl
@@ -21,7 +21,7 @@
 						{{end}}
 						<span class="labels-list tw-ml-1">
 							{{range .Labels}}
-								<a href="?q={{$.Keyword}}&type={{$.ViewType}}&state={{$.State}}&labels={{.ID}}{{if ne $.listType "milestone"}}&milestone={{$.MilestoneID}}{{end}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}&fuzzy={{$.IsFuzzy}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{RenderLabel $.Context ctx.Locale .}}</a>
+								<a href="?q={{$.Keyword}}&type={{$.ViewType}}&state={{$.State}}&labels={{.ID}}{{if ne $.listType "milestone"}}&milestone={{$.MilestoneID}}{{end}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}&fuzzy={{$.IsFuzzy}}{{if $.ShowArchivedLabels}}&archived=true{{end}}" rel="nofollow">{{RenderLabel $.Context ctx.Locale .}}</a>
 							{{end}}
 						</span>
 					</div>

From 68cc61b53736be2923f578d56568a83846b41d2c Mon Sep 17 00:00:00 2001
From: Gusted <postmaster@gusted.xyz>
Date: Tue, 20 Aug 2024 19:09:22 +0200
Subject: [PATCH 2/2] Add integration test

---
 tests/integration/issue_test.go | 36 ++++++++++++++++++++++++---------
 1 file changed, 26 insertions(+), 10 deletions(-)

diff --git a/tests/integration/issue_test.go b/tests/integration/issue_test.go
index 846de8f42c..1df508deb6 100644
--- a/tests/integration/issue_test.go
+++ b/tests/integration/issue_test.go
@@ -1106,17 +1106,33 @@ func TestCommitRefComment(t *testing.T) {
 func TestIssueFilterNoFollow(t *testing.T) {
 	defer tests.PrepareTestEnv(t)()
 
-	req := NewRequest(t, "GET", "/user2/repo1/issues")
-	resp := MakeRequest(t, req, http.StatusOK)
-	htmlDoc := NewHTMLParser(t, resp.Body)
-
 	// Check that every link in the filter list has rel="nofollow".
-	filterLinks := htmlDoc.Find(".issue-list-toolbar-right a[href*=\"?q=\"]")
-	assert.Positive(t, filterLinks.Length())
-	filterLinks.Each(func(i int, link *goquery.Selection) {
-		rel, has := link.Attr("rel")
-		assert.True(t, has)
-		assert.Equal(t, "nofollow", rel)
+	t.Run("Issue lists", func(t *testing.T) {
+		req := NewRequest(t, "GET", "/user2/repo1/issues")
+		resp := MakeRequest(t, req, http.StatusOK)
+		htmlDoc := NewHTMLParser(t, resp.Body)
+
+		filterLinks := htmlDoc.Find(".issue-list-toolbar-right a[href*=\"?q=\"], .labels-list a[href*=\"?q=\"]")
+		assert.Positive(t, filterLinks.Length())
+		filterLinks.Each(func(i int, link *goquery.Selection) {
+			rel, has := link.Attr("rel")
+			assert.True(t, has)
+			assert.Equal(t, "nofollow", rel)
+		})
+	})
+
+	t.Run("Issue page", func(t *testing.T) {
+		req := NewRequest(t, "GET", "/user2/repo1/issues/1")
+		resp := MakeRequest(t, req, http.StatusOK)
+		htmlDoc := NewHTMLParser(t, resp.Body)
+
+		filterLinks := htmlDoc.Find(".timeline .labels-list a[href*=\"?labels=\"], .issue-content-right .labels-list a[href*=\"?labels=\"]")
+		assert.Positive(t, filterLinks.Length())
+		filterLinks.Each(func(i int, link *goquery.Selection) {
+			rel, has := link.Attr("rel")
+			assert.True(t, has)
+			assert.Equal(t, "nofollow", rel)
+		})
 	})
 }