package e2e import ( "net/url" "strconv" "strings" "testing" ) // pageValidPatch is a minimal but well-formed format-patch file. var pageValidPatch = strings.Join([]string{ "From a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2 Mon Sep 17 00:00:00 2001", "From: Test User ", "Date: Mon, 01 Jan 2024 12:00:00 +0000", "Subject: [PATCH] Add f.txt", "", "---", "diff --git a/f.txt b/f.txt", "new file mode 100644", "index 0000000..9daeafb", "--- /dev/null", "+++ b/f.txt", "@@ -0,0 +1 @@", "+x", "", }, "\n") func TestPagination(t *testing.T) { e := newEnv(t) admin := e.admin() e.createRepo(admin, "paged-repo") // 21 issues and 21 patches each spill onto a second page at 20 per page. for i := 1; i <= 21; i++ { admin.post("/paged-repo/issues", url.Values{ "title": {"Issue number " + strconv.Itoa(i)}, "body": {""}, }).mustRedirect("/paged-repo/issues/") } for i := 1; i <= 21; i++ { admin.postMultipart("/paged-repo/patches", url.Values{"title": {"Patch number " + strconv.Itoa(i)}}, file{Field: "patch_file", Name: "bulk.patch", Content: []byte(pageValidPatch)}, ).mustRedirect("/paged-repo/patches/") } t.Run("repo list page 1 shows repos and no pagination when few repos", func(t *testing.T) { if n := admin.get("/").Count(".repo-name"); n == 0 { t.Error("no repos listed") } }) t.Run("issue list page 1 shows at most 20 items", func(t *testing.T) { if n := admin.get("/paged-repo/issues").Count(".issue-item"); n > 20 { t.Errorf("issues on page 1 = %d", n) } }) t.Run("issue list pagination nav appears when more than 20 issues", func(t *testing.T) { if !admin.get("/paged-repo/issues").Has(".pagination") { t.Error("pagination missing") } }) t.Run("issue list page 2 shows remaining issues", func(t *testing.T) { n := admin.get("/paged-repo/issues?page=2").Count(".issue-item") if n == 0 || n > 20 { t.Errorf("issues on page 2 = %d", n) } }) t.Run("issue list page 2 prev link goes to page 1", func(t *testing.T) { href := admin.get("/paged-repo/issues?page=2").Attr(".pagination-prev .pagination-btn", "href") if !strings.Contains(href, "page=1") { t.Errorf("prev href = %q", href) } }) t.Run("issue list page 1 next link goes to page 2", func(t *testing.T) { href := admin.get("/paged-repo/issues").Attr(".pagination-next .pagination-btn", "href") if !strings.Contains(href, "page=2") { t.Errorf("next href = %q", href) } }) t.Run("patch list page 1 shows at most 20 items", func(t *testing.T) { if n := admin.get("/paged-repo/patches").Count(".issue-item"); n > 20 { t.Errorf("patches on page 1 = %d", n) } }) t.Run("patch list pagination nav appears when more than 20 patches", func(t *testing.T) { if !admin.get("/paged-repo/patches").Has(".pagination") { t.Error("pagination missing") } }) t.Run("patch list page 2 shows remaining patches", func(t *testing.T) { if n := admin.get("/paged-repo/patches?page=2").Count(".issue-item"); n == 0 { t.Error("no patches on page 2") } }) t.Run("commit log with few commits shows no cursor nav", func(t *testing.T) { // paged-repo has no commits, so there is nothing to paginate. if n := admin.get("/paged-repo").Count(".commit-cursor-nav"); n != 0 { t.Errorf("commit-cursor-nav count = %d", n) } }) }