From 9bdeee30810329feea6a8578e0495ae1a914c714 Mon Sep 17 00:00:00 2001 From: Gusted Date: Tue, 28 Nov 2023 19:30:08 +0100 Subject: [PATCH] [GITEA] Only pass selected repository IDs to pagination - `ReposParam` is passed to the pagination as value for the `repos` query. It should paginate to other pages with only the selected repositories, which was currently not the case, but was already the case for the links in the selectable items. - Fix the wrong value being passed for issues/pulls lists. - Fix the formatting of repository query value for milestones lists. - Added integration testing. - Resolves https://codeberg.org/forgejo/forgejo/issues/1836 (cherry picked from commit c648e5ab3a341b97807b9a1c4cf312d4acdc08d4) --- routers/web/user/home.go | 17 ++++++- tests/integration/user_test.go | 85 ++++++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+), 2 deletions(-) diff --git a/routers/web/user/home.go b/routers/web/user/home.go index b4fb25dfe0..ccdd1cd69f 100644 --- a/routers/web/user/home.go +++ b/routers/web/user/home.go @@ -315,9 +315,18 @@ func Milestones(ctx *context.Context) { ctx.Data["RepoIDs"] = repoIDs ctx.Data["IsShowClosed"] = isShowClosed + // Convert []int64 to string + reposParam, err := json.Marshal(repoIDs) + if err != nil { + ctx.ServerError("json.Marshal", err) + return + } + + ctx.Data["ReposParam"] = string(reposParam) + pager := context.NewPagination(pagerCount, setting.UI.IssuePagingNum, page, 5) pager.AddParam(ctx, "q", "Keyword") - pager.AddParam(ctx, "repos", "RepoIDs") + pager.AddParam(ctx, "repos", "ReposParam") pager.AddParam(ctx, "sort", "SortType") pager.AddParam(ctx, "state", "State") ctx.Data["Page"] = pager @@ -690,7 +699,11 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) { } // Convert []int64 to string - reposParam, _ := json.Marshal(opts.RepoIDs) + reposParam, err := json.Marshal(selectedRepoIDs) + if err != nil { + ctx.ServerError("json.Marshal", err) + return + } ctx.Data["ReposParam"] = string(reposParam) diff --git a/tests/integration/user_test.go b/tests/integration/user_test.go index ddde415960..2144e7f92b 100644 --- a/tests/integration/user_test.go +++ b/tests/integration/user_test.go @@ -4,7 +4,9 @@ package integration import ( + "fmt" "net/http" + "net/url" "testing" auth_model "code.gitea.io/gitea/models/auth" @@ -297,3 +299,86 @@ func TestUserLocationMapLink(t *testing.T) { htmlDoc := NewHTMLParser(t, resp.Body) htmlDoc.AssertElement(t, `a[href="https://example/foo/A%2Fb"]`, true) } + +func TestPagination(t *testing.T) { + defer tests.PrepareTestEnv(t)() + // Force pagination to almost always happen. + defer test.MockVariableValue(&setting.UI.IssuePagingNum, 1)() + + session := loginUser(t, "user2") + + // Pagination links can be seen multiple times, due to 'last' or 'next' having + // the same link, so take that into consideration when writing asserts. + t.Run("Issues", func(t *testing.T) { + t.Run("No selected repositories", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + req := NewRequest(t, "GET", "/issues") + resp := session.MakeRequest(t, req, http.StatusOK) + + htmlDoc := NewHTMLParser(t, resp.Body) + sel := htmlDoc.Find(`.pagination a.navigation[href="/issues?page=2&q=&type=your_repositories&repos=%5B%5D&sort=recentupdate&state=open&labels="]`) + assert.GreaterOrEqual(t, sel.Length(), 1) + }) + t.Run("Selected repositories", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + escapedQuery := url.QueryEscape("[3,5]") + req := NewRequest(t, "GET", "/issues?repos="+escapedQuery) + resp := session.MakeRequest(t, req, http.StatusOK) + + htmlDoc := NewHTMLParser(t, resp.Body) + sel := htmlDoc.Find(fmt.Sprintf(`.pagination a.navigation[href="/issues?page=2&q=&type=your_repositories&repos=%s&sort=recentupdate&state=open&labels="]`, escapedQuery)) + assert.GreaterOrEqual(t, sel.Length(), 1) + }) + }) + + t.Run("Pulls", func(t *testing.T) { + t.Run("No selected repositories", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + req := NewRequest(t, "GET", "/pulls") + resp := session.MakeRequest(t, req, http.StatusOK) + + htmlDoc := NewHTMLParser(t, resp.Body) + sel := htmlDoc.Find(`.pagination a.navigation[href="/pulls?page=2&q=&type=your_repositories&repos=%5B%5D&sort=recentupdate&state=open&labels="]`) + assert.GreaterOrEqual(t, sel.Length(), 1) + }) + t.Run("Selected repositories", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + escapedQuery := url.QueryEscape("[1,3]") + req := NewRequest(t, "GET", "/pulls?repos="+escapedQuery) + resp := session.MakeRequest(t, req, http.StatusOK) + + htmlDoc := NewHTMLParser(t, resp.Body) + sel := htmlDoc.Find(fmt.Sprintf(`.pagination a.navigation[href="/pulls?page=2&q=&type=your_repositories&repos=%s&sort=recentupdate&state=open&labels="]`, escapedQuery)) + assert.GreaterOrEqual(t, sel.Length(), 1) + }) + }) + + t.Run("Milestones", func(t *testing.T) { + t.Run("No selected repositories", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + escapedQuery := url.QueryEscape("[42,1]") + req := NewRequest(t, "GET", "/milestones") + resp := session.MakeRequest(t, req, http.StatusOK) + + htmlDoc := NewHTMLParser(t, resp.Body) + sel := htmlDoc.Find(fmt.Sprintf(`.pagination a.navigation[href="/milestones?page=2&q=&repos=%s&sort=&state=open"]`, escapedQuery)) + assert.GreaterOrEqual(t, sel.Length(), 1) + }) + t.Run("Selected repositories", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + escapedQuery := url.QueryEscape("[1]") + req := NewRequest(t, "GET", "/milestones?repos="+escapedQuery) + resp := session.MakeRequest(t, req, http.StatusOK) + + htmlDoc := NewHTMLParser(t, resp.Body) + sel := htmlDoc.Find(fmt.Sprintf(`.pagination a.navigation[href="/milestones?page=2&q=&repos=%s&sort=&state=open"]`, escapedQuery)) + assert.GreaterOrEqual(t, sel.Length(), 1) + }) + }) +}