diff --git a/options/locale_next/locale_en-US.json b/options/locale_next/locale_en-US.json
index 624492d532..f8162be167 100644
--- a/options/locale_next/locale_en-US.json
+++ b/options/locale_next/locale_en-US.json
@@ -59,6 +59,8 @@
"repo.issues.filter_modified.hint": "Filter by last modified date",
"repo.issues.filter_sort.hint": "Sort by: created/comments/updated/deadline",
"issues.updated": "updated %s",
+ "issues.filters.labels.exclude": "Exclude label",
+ "issues.filters.labels.unexclude": "Clear exclusion",
"repo.pulls.poster_manage_approval": "Manage approval",
"repo.pulls.poster_requires_approval": "Some workflows are waiting to be reviewed. ",
"repo.pulls.poster_requires_approval.tooltip": "The author of this pull request is not trusted to run workflows triggered by a pull request created from a forked repository or with AGit. The workflows triggered by a `pull_request` event will not run until they are approved.",
diff --git a/templates/shared/label_filter.tmpl b/templates/shared/label_filter.tmpl
index aa9a16f531..1a086a2395 100644
--- a/templates/shared/label_filter.tmpl
+++ b/templates/shared/label_filter.tmpl
@@ -43,7 +43,12 @@
{{RenderLabel ctx .}}
{{template "repo/issue/labels/label_archived" .}}
-
+
+ {{$exclusionTooltip := ctx.Locale.TrString "issues.filters.labels.exclude"}}
+ {{if .IsExcluded}}
+ {{$exclusionTooltip = ctx.Locale.TrString "issues.filters.labels.unexclude"}}
+ {{end}}
+
{{svg "octicon-no-entry"}}
diff --git a/tests/integration/issue_list_filters_test.go b/tests/integration/issue_list_filters_test.go
new file mode 100644
index 0000000000..35a1891665
--- /dev/null
+++ b/tests/integration/issue_list_filters_test.go
@@ -0,0 +1,360 @@
+// Copyright 2024 The Forgejo Authors
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package integration
+
+import (
+ "net/http"
+ "testing"
+
+ "forgejo.org/modules/translation"
+ "forgejo.org/tests"
+
+ "github.com/PuerkitoBio/goquery"
+ "github.com/stretchr/testify/assert"
+)
+
+// Tests for contents of pages .../issues and .../pulls
+
+func TestIssueFilterLabels(t *testing.T) {
+ defer tests.PrepareTestEnv(t)()
+
+ t.Run("Exclusion tooltips", func(t *testing.T) {
+ defer tests.PrintCurrentTest(t)()
+
+ url := "/user2/repo1/issues?labels=-2"
+ page := NewHTMLParser(t, MakeRequest(t, NewRequest(t, "GET", url), http.StatusOK).Body)
+
+ page.AssertElement(t, ".label-filter .menu .item:has(a[data-label-id='1']) button[data-tooltip-content='Exclude label']", true)
+ page.AssertElement(t, ".label-filter .menu .item:has(a[data-label-id='2']) button[data-tooltip-content='Clear exclusion']", true)
+ })
+}
+
+func TestIssueSorting(t *testing.T) {
+ defer tests.PrepareTestEnv(t)()
+
+ t.Run("Dropdown content", func(t *testing.T) {
+ defer tests.PrintCurrentTest(t)()
+
+ req := NewRequest(t, "GET", "/user2/repo1/issues")
+ resp := MakeRequest(t, req, http.StatusOK)
+ htmlDoc := NewHTMLParser(t, resp.Body)
+
+ assert.Equal(t,
+ 9,
+ htmlDoc.Find(`.list-header-sort .menu a`).Length(),
+ "Wrong amount of sort options in dropdown")
+
+ menuItemsHTML := htmlDoc.Find(`.list-header-sort .menu`).Text()
+ locale := translation.NewLocale("en-US")
+ for _, key := range []string{
+ "relevance",
+ "latest",
+ "oldest",
+ "recentupdate",
+ "leastupdate",
+ "mostcomment",
+ "leastcomment",
+ "nearduedate",
+ "farduedate",
+ } {
+ assert.Contains(t,
+ menuItemsHTML,
+ locale.Tr("repo.issues.filter_sort."+key),
+ "Sort option %s ('%s') not found in dropdown", key, locale.Tr("repo.issues.filter_sort."+key))
+ }
+ })
+}
+
+func TestIssueFilterLinks(t *testing.T) {
+ defer tests.PrepareTestEnv(t)()
+
+ t.Run("No filters", func(t *testing.T) {
+ defer tests.PrintCurrentTest(t)()
+
+ req := NewRequest(t, "GET", "/user2/repo1/issues")
+ resp := MakeRequest(t, req, http.StatusOK)
+ htmlDoc := NewHTMLParser(t, resp.Body)
+
+ called := false
+ htmlDoc.Find("#issue-filters a[href^='?']").Each(func(_ int, s *goquery.Selection) {
+ called = true
+ href, _ := s.Attr("href")
+ assert.Contains(t, href, "?q=&")
+ assert.Contains(t, href, "&type=")
+ assert.Contains(t, href, "&sort=")
+ assert.Contains(t, href, "&state=")
+ assert.Contains(t, href, "&labels=")
+ assert.Contains(t, href, "&milestone=")
+ assert.Contains(t, href, "&project=")
+ assert.Contains(t, href, "&assignee=")
+ assert.Contains(t, href, "&poster=")
+ })
+ assert.True(t, called)
+ })
+
+ t.Run("Keyword", func(t *testing.T) {
+ defer tests.PrintCurrentTest(t)()
+
+ req := NewRequest(t, "GET", "/user2/repo1/issues?q=search-on-this")
+ resp := MakeRequest(t, req, http.StatusOK)
+ htmlDoc := NewHTMLParser(t, resp.Body)
+
+ called := false
+ htmlDoc.Find("#issue-filters a[href^='?']").Each(func(_ int, s *goquery.Selection) {
+ called = true
+ href, _ := s.Attr("href")
+ assert.Contains(t, href, "?q=search-on-this")
+ assert.Contains(t, href, "&type=")
+ assert.Contains(t, href, "&sort=")
+ assert.Contains(t, href, "&state=")
+ assert.Contains(t, href, "&labels=")
+ assert.Contains(t, href, "&milestone=")
+ assert.Contains(t, href, "&project=")
+ assert.Contains(t, href, "&assignee=")
+ assert.Contains(t, href, "&poster=")
+ })
+ assert.True(t, called)
+ })
+
+ t.Run("Sort", func(t *testing.T) {
+ defer tests.PrintCurrentTest(t)()
+
+ req := NewRequest(t, "GET", "/user2/repo1/issues?sort=oldest")
+ resp := MakeRequest(t, req, http.StatusOK)
+ htmlDoc := NewHTMLParser(t, resp.Body)
+
+ called := false
+ htmlDoc.Find("#issue-filters a[href^='?']:not(.list-header-sort a)").Each(func(_ int, s *goquery.Selection) {
+ called = true
+ href, _ := s.Attr("href")
+ assert.Contains(t, href, "?q=&")
+ assert.Contains(t, href, "&type=")
+ assert.Contains(t, href, "&sort=oldest")
+ assert.Contains(t, href, "&state=")
+ assert.Contains(t, href, "&labels=")
+ assert.Contains(t, href, "&milestone=")
+ assert.Contains(t, href, "&project=")
+ assert.Contains(t, href, "&assignee=")
+ assert.Contains(t, href, "&poster=")
+ })
+ assert.True(t, called)
+ })
+
+ t.Run("Type", func(t *testing.T) {
+ defer tests.PrintCurrentTest(t)()
+
+ req := NewRequest(t, "GET", "/user2/repo1/issues?type=assigned")
+ resp := MakeRequest(t, req, http.StatusOK)
+ htmlDoc := NewHTMLParser(t, resp.Body)
+
+ called := false
+ htmlDoc.Find("#issue-filters a[href^='?']:not(.list-header-type a)").Each(func(_ int, s *goquery.Selection) {
+ called = true
+ href, _ := s.Attr("href")
+ assert.Contains(t, href, "?q=&")
+ assert.Contains(t, href, "&type=assigned")
+ assert.Contains(t, href, "&sort=")
+ assert.Contains(t, href, "&state=")
+ assert.Contains(t, href, "&labels=")
+ assert.Contains(t, href, "&milestone=")
+ assert.Contains(t, href, "&project=")
+ assert.Contains(t, href, "&assignee=")
+ assert.Contains(t, href, "&poster=")
+ })
+ assert.True(t, called)
+ })
+
+ t.Run("State", func(t *testing.T) {
+ defer tests.PrintCurrentTest(t)()
+
+ req := NewRequest(t, "GET", "/user2/repo1/issues?state=closed")
+ resp := MakeRequest(t, req, http.StatusOK)
+ htmlDoc := NewHTMLParser(t, resp.Body)
+
+ called := false
+ htmlDoc.Find("#issue-filters a[href^='?']:not(.issue-list-toolbar-left a)").Each(func(_ int, s *goquery.Selection) {
+ called = true
+ href, _ := s.Attr("href")
+ assert.Contains(t, href, "?q=&")
+ assert.Contains(t, href, "&type=")
+ assert.Contains(t, href, "&sort=")
+ assert.Contains(t, href, "&state=closed")
+ assert.Contains(t, href, "&labels=")
+ assert.Contains(t, href, "&milestone=")
+ assert.Contains(t, href, "&project=")
+ assert.Contains(t, href, "&assignee=")
+ assert.Contains(t, href, "&poster=")
+ })
+ assert.True(t, called)
+ })
+
+ t.Run("Milestone", func(t *testing.T) {
+ defer tests.PrintCurrentTest(t)()
+
+ req := NewRequest(t, "GET", "/user2/repo1/issues?milestone=1")
+ resp := MakeRequest(t, req, http.StatusOK)
+ htmlDoc := NewHTMLParser(t, resp.Body)
+
+ called := false
+ htmlDoc.Find("#issue-filters a[href^='?']:not(.list-header-milestone a)").Each(func(_ int, s *goquery.Selection) {
+ called = true
+ href, _ := s.Attr("href")
+ assert.Contains(t, href, "?q=&")
+ assert.Contains(t, href, "&type=")
+ assert.Contains(t, href, "&sort=")
+ assert.Contains(t, href, "&state=")
+ assert.Contains(t, href, "&labels=")
+ assert.Contains(t, href, "&milestone=1")
+ assert.Contains(t, href, "&project=")
+ assert.Contains(t, href, "&assignee=")
+ assert.Contains(t, href, "&poster=")
+ })
+ assert.True(t, called)
+ })
+
+ t.Run("Milestone", func(t *testing.T) {
+ defer tests.PrintCurrentTest(t)()
+
+ req := NewRequest(t, "GET", "/user2/repo1/issues?milestone=1")
+ resp := MakeRequest(t, req, http.StatusOK)
+ htmlDoc := NewHTMLParser(t, resp.Body)
+
+ called := false
+ htmlDoc.Find("#issue-filters a[href^='?']:not(.list-header-milestone a)").Each(func(_ int, s *goquery.Selection) {
+ called = true
+ href, _ := s.Attr("href")
+ assert.Contains(t, href, "?q=&")
+ assert.Contains(t, href, "&type=")
+ assert.Contains(t, href, "&sort=")
+ assert.Contains(t, href, "&state=")
+ assert.Contains(t, href, "&labels=")
+ assert.Contains(t, href, "&milestone=1")
+ assert.Contains(t, href, "&project=")
+ assert.Contains(t, href, "&assignee=")
+ assert.Contains(t, href, "&poster=")
+ })
+ assert.True(t, called)
+ })
+
+ t.Run("Project", func(t *testing.T) {
+ defer tests.PrintCurrentTest(t)()
+
+ req := NewRequest(t, "GET", "/user2/repo1/issues?project=1")
+ resp := MakeRequest(t, req, http.StatusOK)
+ htmlDoc := NewHTMLParser(t, resp.Body)
+
+ called := false
+ htmlDoc.Find("#issue-filters a[href^='?']:not(.list-header-project a)").Each(func(_ int, s *goquery.Selection) {
+ called = true
+ href, _ := s.Attr("href")
+ assert.Contains(t, href, "?q=&")
+ assert.Contains(t, href, "&type=")
+ assert.Contains(t, href, "&sort=")
+ assert.Contains(t, href, "&state=")
+ assert.Contains(t, href, "&labels=")
+ assert.Contains(t, href, "&milestone=")
+ assert.Contains(t, href, "&project=1")
+ assert.Contains(t, href, "&assignee=")
+ assert.Contains(t, href, "&poster=")
+ })
+ assert.True(t, called)
+ })
+
+ t.Run("Assignee", func(t *testing.T) {
+ defer tests.PrintCurrentTest(t)()
+
+ req := NewRequest(t, "GET", "/user2/repo1/issues?assignee=1")
+ resp := MakeRequest(t, req, http.StatusOK)
+ htmlDoc := NewHTMLParser(t, resp.Body)
+
+ called := false
+ htmlDoc.Find("#issue-filters a[href^='?']:not(.list-header-assignee a)").Each(func(_ int, s *goquery.Selection) {
+ called = true
+ href, _ := s.Attr("href")
+ assert.Contains(t, href, "?q=&")
+ assert.Contains(t, href, "&type=")
+ assert.Contains(t, href, "&sort=")
+ assert.Contains(t, href, "&state=")
+ assert.Contains(t, href, "&labels=")
+ assert.Contains(t, href, "&milestone=")
+ assert.Contains(t, href, "&project=")
+ assert.Contains(t, href, "&assignee=1")
+ assert.Contains(t, href, "&poster=")
+ })
+ assert.True(t, called)
+ })
+
+ t.Run("Poster", func(t *testing.T) {
+ defer tests.PrintCurrentTest(t)()
+
+ req := NewRequest(t, "GET", "/user2/repo1/issues?poster=1")
+ resp := MakeRequest(t, req, http.StatusOK)
+ htmlDoc := NewHTMLParser(t, resp.Body)
+
+ called := false
+ htmlDoc.Find("#issue-filters a[href^='?']:not(.list-header-poster a)").Each(func(_ int, s *goquery.Selection) {
+ called = true
+ href, _ := s.Attr("href")
+ assert.Contains(t, href, "?q=&")
+ assert.Contains(t, href, "&type=")
+ assert.Contains(t, href, "&sort=")
+ assert.Contains(t, href, "&state=")
+ assert.Contains(t, href, "&labels=")
+ assert.Contains(t, href, "&milestone=")
+ assert.Contains(t, href, "&project=")
+ assert.Contains(t, href, "&assignee=")
+ assert.Contains(t, href, "&poster=1")
+ })
+ assert.True(t, called)
+ })
+
+ t.Run("Labels", func(t *testing.T) {
+ defer tests.PrintCurrentTest(t)()
+
+ req := NewRequest(t, "GET", "/user2/repo1/issues?labels=1")
+ resp := MakeRequest(t, req, http.StatusOK)
+ htmlDoc := NewHTMLParser(t, resp.Body)
+
+ called := false
+ htmlDoc.Find("#issue-filters a[href^='?']:not(.label-filter a)").Each(func(_ int, s *goquery.Selection) {
+ called = true
+ href, _ := s.Attr("href")
+ assert.Contains(t, href, "?q=&")
+ assert.Contains(t, href, "&type=")
+ assert.Contains(t, href, "&sort=")
+ assert.Contains(t, href, "&state=")
+ assert.Contains(t, href, "&labels=1")
+ assert.Contains(t, href, "&milestone=")
+ assert.Contains(t, href, "&project=")
+ assert.Contains(t, href, "&assignee=")
+ assert.Contains(t, href, "&poster=")
+ })
+ assert.True(t, called)
+ })
+
+ t.Run("Archived labels", func(t *testing.T) {
+ defer tests.PrintCurrentTest(t)()
+
+ req := NewRequest(t, "GET", "/user2/repo1/issues?archived=true")
+ resp := MakeRequest(t, req, http.StatusOK)
+ htmlDoc := NewHTMLParser(t, resp.Body)
+
+ called := false
+ htmlDoc.Find("#issue-filters a[href^='?']").Each(func(_ int, s *goquery.Selection) {
+ called = true
+ href, _ := s.Attr("href")
+ assert.Contains(t, href, "?q=&")
+ assert.Contains(t, href, "&type=")
+ assert.Contains(t, href, "&sort=")
+ assert.Contains(t, href, "&state=")
+ assert.Contains(t, href, "&labels=")
+ assert.Contains(t, href, "&milestone=")
+ assert.Contains(t, href, "&project=")
+ assert.Contains(t, href, "&assignee=")
+ assert.Contains(t, href, "&poster=")
+ assert.Contains(t, href, "&archived=true")
+ })
+ assert.True(t, called)
+ })
+}
diff --git a/tests/integration/repo_test.go b/tests/integration/repo_test.go
index c7bfad32bd..1b4a574f13 100644
--- a/tests/integration/repo_test.go
+++ b/tests/integration/repo_test.go
@@ -1219,335 +1219,6 @@ func TestFileHistoryPager(t *testing.T) {
})
}
-func TestRepoIssueSorting(t *testing.T) {
- defer tests.PrepareTestEnv(t)()
-
- t.Run("Dropdown content", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- req := NewRequest(t, "GET", "/user2/repo1/issues")
- resp := MakeRequest(t, req, http.StatusOK)
- htmlDoc := NewHTMLParser(t, resp.Body)
-
- assert.Equal(t,
- 9,
- htmlDoc.Find(`.list-header-sort .menu a`).Length(),
- "Wrong amount of sort options in dropdown")
-
- menuItemsHTML := htmlDoc.Find(`.list-header-sort .menu`).Text()
- locale := translation.NewLocale("en-US")
- for _, key := range []string{
- "relevance",
- "latest",
- "oldest",
- "recentupdate",
- "leastupdate",
- "mostcomment",
- "leastcomment",
- "nearduedate",
- "farduedate",
- } {
- assert.Contains(t,
- menuItemsHTML,
- locale.Tr("repo.issues.filter_sort."+key),
- "Sort option %s ('%s') not found in dropdown", key, locale.Tr("repo.issues.filter_sort."+key))
- }
- })
-}
-
-func TestRepoIssueFilterLinks(t *testing.T) {
- defer tests.PrepareTestEnv(t)()
-
- t.Run("No filters", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- req := NewRequest(t, "GET", "/user2/repo1/issues")
- resp := MakeRequest(t, req, http.StatusOK)
- htmlDoc := NewHTMLParser(t, resp.Body)
-
- called := false
- htmlDoc.Find("#issue-filters a[href^='?']").Each(func(_ int, s *goquery.Selection) {
- called = true
- href, _ := s.Attr("href")
- assert.Contains(t, href, "?q=&")
- assert.Contains(t, href, "&type=")
- assert.Contains(t, href, "&sort=")
- assert.Contains(t, href, "&state=")
- assert.Contains(t, href, "&labels=")
- assert.Contains(t, href, "&milestone=")
- assert.Contains(t, href, "&project=")
- assert.Contains(t, href, "&assignee=")
- assert.Contains(t, href, "&poster=")
- })
- assert.True(t, called)
- })
-
- t.Run("Keyword", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- req := NewRequest(t, "GET", "/user2/repo1/issues?q=search-on-this")
- resp := MakeRequest(t, req, http.StatusOK)
- htmlDoc := NewHTMLParser(t, resp.Body)
-
- called := false
- htmlDoc.Find("#issue-filters a[href^='?']").Each(func(_ int, s *goquery.Selection) {
- called = true
- href, _ := s.Attr("href")
- assert.Contains(t, href, "?q=search-on-this")
- assert.Contains(t, href, "&type=")
- assert.Contains(t, href, "&sort=")
- assert.Contains(t, href, "&state=")
- assert.Contains(t, href, "&labels=")
- assert.Contains(t, href, "&milestone=")
- assert.Contains(t, href, "&project=")
- assert.Contains(t, href, "&assignee=")
- assert.Contains(t, href, "&poster=")
- })
- assert.True(t, called)
- })
-
- t.Run("Sort", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- req := NewRequest(t, "GET", "/user2/repo1/issues?sort=oldest")
- resp := MakeRequest(t, req, http.StatusOK)
- htmlDoc := NewHTMLParser(t, resp.Body)
-
- called := false
- htmlDoc.Find("#issue-filters a[href^='?']:not(.list-header-sort a)").Each(func(_ int, s *goquery.Selection) {
- called = true
- href, _ := s.Attr("href")
- assert.Contains(t, href, "?q=&")
- assert.Contains(t, href, "&type=")
- assert.Contains(t, href, "&sort=oldest")
- assert.Contains(t, href, "&state=")
- assert.Contains(t, href, "&labels=")
- assert.Contains(t, href, "&milestone=")
- assert.Contains(t, href, "&project=")
- assert.Contains(t, href, "&assignee=")
- assert.Contains(t, href, "&poster=")
- })
- assert.True(t, called)
- })
-
- t.Run("Type", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- req := NewRequest(t, "GET", "/user2/repo1/issues?type=assigned")
- resp := MakeRequest(t, req, http.StatusOK)
- htmlDoc := NewHTMLParser(t, resp.Body)
-
- called := false
- htmlDoc.Find("#issue-filters a[href^='?']:not(.list-header-type a)").Each(func(_ int, s *goquery.Selection) {
- called = true
- href, _ := s.Attr("href")
- assert.Contains(t, href, "?q=&")
- assert.Contains(t, href, "&type=assigned")
- assert.Contains(t, href, "&sort=")
- assert.Contains(t, href, "&state=")
- assert.Contains(t, href, "&labels=")
- assert.Contains(t, href, "&milestone=")
- assert.Contains(t, href, "&project=")
- assert.Contains(t, href, "&assignee=")
- assert.Contains(t, href, "&poster=")
- })
- assert.True(t, called)
- })
-
- t.Run("State", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- req := NewRequest(t, "GET", "/user2/repo1/issues?state=closed")
- resp := MakeRequest(t, req, http.StatusOK)
- htmlDoc := NewHTMLParser(t, resp.Body)
-
- called := false
- htmlDoc.Find("#issue-filters a[href^='?']:not(.issue-list-toolbar-left a)").Each(func(_ int, s *goquery.Selection) {
- called = true
- href, _ := s.Attr("href")
- assert.Contains(t, href, "?q=&")
- assert.Contains(t, href, "&type=")
- assert.Contains(t, href, "&sort=")
- assert.Contains(t, href, "&state=closed")
- assert.Contains(t, href, "&labels=")
- assert.Contains(t, href, "&milestone=")
- assert.Contains(t, href, "&project=")
- assert.Contains(t, href, "&assignee=")
- assert.Contains(t, href, "&poster=")
- })
- assert.True(t, called)
- })
-
- t.Run("Milestone", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- req := NewRequest(t, "GET", "/user2/repo1/issues?milestone=1")
- resp := MakeRequest(t, req, http.StatusOK)
- htmlDoc := NewHTMLParser(t, resp.Body)
-
- called := false
- htmlDoc.Find("#issue-filters a[href^='?']:not(.list-header-milestone a)").Each(func(_ int, s *goquery.Selection) {
- called = true
- href, _ := s.Attr("href")
- assert.Contains(t, href, "?q=&")
- assert.Contains(t, href, "&type=")
- assert.Contains(t, href, "&sort=")
- assert.Contains(t, href, "&state=")
- assert.Contains(t, href, "&labels=")
- assert.Contains(t, href, "&milestone=1")
- assert.Contains(t, href, "&project=")
- assert.Contains(t, href, "&assignee=")
- assert.Contains(t, href, "&poster=")
- })
- assert.True(t, called)
- })
-
- t.Run("Milestone", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- req := NewRequest(t, "GET", "/user2/repo1/issues?milestone=1")
- resp := MakeRequest(t, req, http.StatusOK)
- htmlDoc := NewHTMLParser(t, resp.Body)
-
- called := false
- htmlDoc.Find("#issue-filters a[href^='?']:not(.list-header-milestone a)").Each(func(_ int, s *goquery.Selection) {
- called = true
- href, _ := s.Attr("href")
- assert.Contains(t, href, "?q=&")
- assert.Contains(t, href, "&type=")
- assert.Contains(t, href, "&sort=")
- assert.Contains(t, href, "&state=")
- assert.Contains(t, href, "&labels=")
- assert.Contains(t, href, "&milestone=1")
- assert.Contains(t, href, "&project=")
- assert.Contains(t, href, "&assignee=")
- assert.Contains(t, href, "&poster=")
- })
- assert.True(t, called)
- })
-
- t.Run("Project", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- req := NewRequest(t, "GET", "/user2/repo1/issues?project=1")
- resp := MakeRequest(t, req, http.StatusOK)
- htmlDoc := NewHTMLParser(t, resp.Body)
-
- called := false
- htmlDoc.Find("#issue-filters a[href^='?']:not(.list-header-project a)").Each(func(_ int, s *goquery.Selection) {
- called = true
- href, _ := s.Attr("href")
- assert.Contains(t, href, "?q=&")
- assert.Contains(t, href, "&type=")
- assert.Contains(t, href, "&sort=")
- assert.Contains(t, href, "&state=")
- assert.Contains(t, href, "&labels=")
- assert.Contains(t, href, "&milestone=")
- assert.Contains(t, href, "&project=1")
- assert.Contains(t, href, "&assignee=")
- assert.Contains(t, href, "&poster=")
- })
- assert.True(t, called)
- })
-
- t.Run("Assignee", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- req := NewRequest(t, "GET", "/user2/repo1/issues?assignee=1")
- resp := MakeRequest(t, req, http.StatusOK)
- htmlDoc := NewHTMLParser(t, resp.Body)
-
- called := false
- htmlDoc.Find("#issue-filters a[href^='?']:not(.list-header-assignee a)").Each(func(_ int, s *goquery.Selection) {
- called = true
- href, _ := s.Attr("href")
- assert.Contains(t, href, "?q=&")
- assert.Contains(t, href, "&type=")
- assert.Contains(t, href, "&sort=")
- assert.Contains(t, href, "&state=")
- assert.Contains(t, href, "&labels=")
- assert.Contains(t, href, "&milestone=")
- assert.Contains(t, href, "&project=")
- assert.Contains(t, href, "&assignee=1")
- assert.Contains(t, href, "&poster=")
- })
- assert.True(t, called)
- })
-
- t.Run("Poster", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- req := NewRequest(t, "GET", "/user2/repo1/issues?poster=1")
- resp := MakeRequest(t, req, http.StatusOK)
- htmlDoc := NewHTMLParser(t, resp.Body)
-
- called := false
- htmlDoc.Find("#issue-filters a[href^='?']:not(.list-header-poster a)").Each(func(_ int, s *goquery.Selection) {
- called = true
- href, _ := s.Attr("href")
- assert.Contains(t, href, "?q=&")
- assert.Contains(t, href, "&type=")
- assert.Contains(t, href, "&sort=")
- assert.Contains(t, href, "&state=")
- assert.Contains(t, href, "&labels=")
- assert.Contains(t, href, "&milestone=")
- assert.Contains(t, href, "&project=")
- assert.Contains(t, href, "&assignee=")
- assert.Contains(t, href, "&poster=1")
- })
- assert.True(t, called)
- })
-
- t.Run("Labels", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- req := NewRequest(t, "GET", "/user2/repo1/issues?labels=1")
- resp := MakeRequest(t, req, http.StatusOK)
- htmlDoc := NewHTMLParser(t, resp.Body)
-
- called := false
- htmlDoc.Find("#issue-filters a[href^='?']:not(.label-filter a)").Each(func(_ int, s *goquery.Selection) {
- called = true
- href, _ := s.Attr("href")
- assert.Contains(t, href, "?q=&")
- assert.Contains(t, href, "&type=")
- assert.Contains(t, href, "&sort=")
- assert.Contains(t, href, "&state=")
- assert.Contains(t, href, "&labels=1")
- assert.Contains(t, href, "&milestone=")
- assert.Contains(t, href, "&project=")
- assert.Contains(t, href, "&assignee=")
- assert.Contains(t, href, "&poster=")
- })
- assert.True(t, called)
- })
-
- t.Run("Archived labels", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- req := NewRequest(t, "GET", "/user2/repo1/issues?archived=true")
- resp := MakeRequest(t, req, http.StatusOK)
- htmlDoc := NewHTMLParser(t, resp.Body)
-
- called := false
- htmlDoc.Find("#issue-filters a[href^='?']").Each(func(_ int, s *goquery.Selection) {
- called = true
- href, _ := s.Attr("href")
- assert.Contains(t, href, "?q=&")
- assert.Contains(t, href, "&type=")
- assert.Contains(t, href, "&sort=")
- assert.Contains(t, href, "&state=")
- assert.Contains(t, href, "&labels=")
- assert.Contains(t, href, "&milestone=")
- assert.Contains(t, href, "&project=")
- assert.Contains(t, href, "&assignee=")
- assert.Contains(t, href, "&poster=")
- assert.Contains(t, href, "&archived=true")
- })
- assert.True(t, called)
- })
-}
-
func TestRepoSubmoduleView(t *testing.T) {
onApplicationRun(t, func(t *testing.T, u *url.URL) {
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})