test: share the first-page and clock helpers

writeFirstPage answers paged listings in app and services tests,
testNow replaces the copied clock, withoutANSI the second color
stripper, and the single-entry table test becomes a plain test.

Signed-off-by: bircni <bircni@icloud.com>
This commit is contained in:
bircni committed 2026-10-12 14:25:38 +02:00
1 parent 83924892ff
commit dc24231ebc
23 files changed
+66 -105

No files matched your search

+1 -1
View File
@@ -122,7 +122,7 @@ func TestCommentGroupCommentsLikeGh(t *testing.T) {
}))
defer server.Close()
deps, out, diagnostics := serverDeps(t, server.URL)
deps.Now = func() time.Time { return time.Date(2026, 10, 11, 20, 0, 0, 0, time.UTC) }
deps.Now = func() time.Time { return testNow }
run := func(args ...string) error {
out.Reset()
diagnostics.Reset()
+1 -1
View File
@@ -81,7 +81,7 @@ func TestSearchTables(t *testing.T) {
}))
defer server.Close()
deps, out, diagnostics := serverDeps(t, server.URL)
deps.Now = func() time.Time { return time.Date(2026, 10, 11, 20, 0, 0, 0, time.UTC) }
deps.Now = func() time.Time { return testNow }
deps.Getenv = serverEnv(server.URL, map[string]string{"NO_COLOR": "1"})
plainOutput(t, deps)
deps.Streams.OutTTY = true
+2 -6
View File
@@ -104,16 +104,12 @@ func TestPullViewCommentsIncludeReviews(t *testing.T) {
case "/api/v1/repos/alice/project/issues/4/comments":
_, _ = w.Write([]byte(`[{"body":"Looks close","user":{"login":"carol"},"created_at":"2026-01-02T00:00:00Z"}]`))
case "/api/v1/repos/alice/project/pulls/4/reviews":
if r.URL.Query().Get("page") != "1" {
_, _ = w.Write([]byte(`[]`))
return
}
_, _ = w.Write([]byte(`[
writeFirstPage(w, r, `[
{"id":1,"body":"Please rename","state":"REQUEST_CHANGES","user":{"login":"alice"},"submitted_at":"2026-01-01T12:00:00Z","comments_count":1},
{"id":2,"body":"","state":"APPROVED","user":{"login":"dave"},"submitted_at":"2026-01-03T00:00:00Z"},
{"id":3,"body":"Draft","state":"PENDING","user":{"login":"erin"},"submitted_at":"2026-01-03T00:00:00Z"},
{"id":4,"body":"Great","state":"APPROVED","user":{"login":"alice"},"submitted_at":"2026-01-03T06:00:00Z"}
]`))
]`)
case "/api/v1/repos/alice/project/pulls/4/reviews/1/comments":
_, _ = w.Write([]byte(`[{"id":9,"body":"Typo here","path":"main.go","position":12,"user":{"login":"alice"},"created_at":"2026-01-01T12:00:00Z"}]`))
default:
+12
View File
@@ -19,6 +19,7 @@ import (
"regexp"
"strings"
"testing"
"time"
"gitea.dev/tea/internal/auth"
"gitea.dev/tea/internal/clierr"
@@ -336,3 +337,14 @@ func plainOutput(t *testing.T, deps Dependencies) {
return nil
}))
}
// writeFirstPage answers the first page of a listing with page and every later page with [].
func writeFirstPage(w http.ResponseWriter, r *http.Request, page string) {
if r.URL.Query().Get("page") != "1" {
page = `[]`
}
_, _ = w.Write([]byte(page))
}
// testNow is the clock of tests that show relative times.
var testNow = time.Date(2026, 10, 11, 20, 0, 0, 0, time.UTC)
+18 -27
View File
@@ -151,7 +151,7 @@ func TestMultiItemHumanOutputPagesOnce(t *testing.T) {
server := newAuthenticatedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch r.URL.Path {
case "/api/v1/repos/alice/project/milestones":
writeMilestones(w, r, `[{"id":3,"title":"v1"}]`)
writeFirstPage(w, r, `[{"id":3,"title":"v1"}]`)
case "/api/v1/repos/alice/project/issues":
_, _ = w.Write([]byte("[" + issue(1) + "," + issue(2) + "]"))
case "/api/v1/repos/alice/project/issues/1", "/api/v1/repos/alice/project/issues/2":
@@ -223,31 +223,22 @@ func TestListsFitTheTerminalAndSplitWhenPiped(t *testing.T) {
`{"number":5,"title":"支持中文路径 (support CJK paths)","state":"open","user":{"login":""}}]`))
}))
defer server.Close()
for group, want := range map[string][2]string{
"issue": {
"6\tA very long issue title that keeps going and going to see how list output handles wrapping\t\topen\tissue\talice\t\n" +
"5\t支持中文路径 (support CJK paths)\t\topen\tissue\t\t\n",
"Showing 2 of 2 open issues in alice/project\n\n" +
"ID TITLE LABELS AUTHOR UPDATED\n" +
"#6 A very long issue ti… alice\n" +
"#5 支持中文路径 (suppor…\n",
},
} {
t.Run(group, func(t *testing.T) {
deps, out, _ := serverDeps(t, server.URL)
args := []string{group, "list", "-R", "alice/project"}
require.NoError(t, Execute(context.Background(), deps, args))
require.Equal(t, want[0], out.String())
deps, out, _ := serverDeps(t, server.URL)
args := []string{"issue", "list", "-R", "alice/project"}
require.NoError(t, Execute(context.Background(), deps, args))
require.Equal(t, "6\tA very long issue title that keeps going and going to see how list output handles wrapping\t\topen\tissue\talice\t\n"+
"5\t支持中文路径 (support CJK paths)\t\topen\tissue\t\t\n", out.String())
out.Reset()
deps.Streams.OutTTY, deps.Streams.Width = true, 50
deps.Getenv = serverEnv(server.URL, map[string]string{"NO_COLOR": "1"})
require.NoError(t, Execute(context.Background(), deps, args))
require.Equal(t, want[1], stripLinks(out.String()))
for _, line := range strings.Split(strings.TrimSpace(out.String()), "\n") {
require.LessOrEqual(t, runewidth.StringWidth(stripLinks(line)), 50, line)
}
})
out.Reset()
deps.Streams.OutTTY, deps.Streams.Width = true, 50
deps.Getenv = serverEnv(server.URL, map[string]string{"NO_COLOR": "1"})
require.NoError(t, Execute(context.Background(), deps, args))
require.Equal(t, "Showing 2 of 2 open issues in alice/project\n\n"+
"ID TITLE LABELS AUTHOR UPDATED\n"+
"#6 A very long issue ti… alice\n"+
"#5 支持中文路径 (suppor…\n", stripLinks(out.String()))
for _, line := range strings.Split(strings.TrimSpace(out.String()), "\n") {
require.LessOrEqual(t, runewidth.StringWidth(stripLinks(line)), 50, line)
}
}
@@ -265,7 +256,7 @@ func stripLinks(s string) string {
// outputApplication returns an application over deps and a command writing to its streams.
func outputApplication(deps Dependencies, json string) (*application, *cobra.Command) {
deps.Now = func() time.Time { return time.Date(2026, 10, 11, 20, 0, 0, 0, time.UTC) }
deps.Now = func() time.Time { return testNow }
a := &application{deps: deps, options: options{json: json}}
cmd := &cobra.Command{Use: "list"}
cmd.SetOut(deps.Streams.Out)
@@ -335,7 +326,7 @@ func TestWriteView(t *testing.T) {
view := func(item listed) terminal.View {
return terminal.View{
Title: item.Title, ID: fmt.Sprintf("#%d", item.Number), Badges: []terminal.Cell{{Text: "Open", Color: "green"}},
Meta: "alice opened " + terminal.RelativeTime(time.Date(2026, 10, 11, 20, 0, 0, 0, time.UTC), item.Updated), Body: "Steps", Kind: "issue", URL: "https://example.org/1",
Meta: "alice opened " + terminal.RelativeTime(testNow, item.Updated), Body: "Steps", Kind: "issue", URL: "https://example.org/1",
}
}
item := listed{1, "Login fails", time.Date(2026, 10, 11, 18, 0, 0, 0, time.UTC)}
+1 -1
View File
@@ -105,7 +105,7 @@ func TestAttachmentTablesDownloadsAndDoneLines(t *testing.T) {
}))
defer server.Close()
deps, out, diagnostics := serverDeps(t, server.URL)
deps.Now = func() time.Time { return time.Date(2026, 10, 11, 20, 0, 0, 0, time.UTC) }
deps.Now = func() time.Time { return testNow }
deps.Getenv = serverEnv(server.URL, map[string]string{"NO_COLOR": "1"})
plainOutput(t, deps)
run := func(tty bool, args ...string) error {
+1 -5
View File
@@ -82,11 +82,7 @@ func TestIssueEditAddAndRemoveLabels(t *testing.T) {
case r.URL.Path == "/api/v1/orgs/alice":
w.WriteHeader(http.StatusNotFound)
case r.URL.Path == "/api/v1/repos/alice/project/labels":
if r.URL.Query().Get("page") != "1" {
_, _ = w.Write([]byte(`[]`))
return
}
_, _ = w.Write([]byte(`[{"id":1,"name":"bug"},{"id":2,"name":"docs"},{"id":3,"name":"help"}]`))
writeFirstPage(w, r, `[{"id":1,"name":"bug"},{"id":2,"name":"docs"},{"id":3,"name":"help"}]`)
case r.Method == http.MethodGet && r.URL.Path == "/api/v1/repos/alice/project/issues/7":
_, _ = w.Write([]byte(`{"number":7,"labels":[{"id":1,"name":"bug"},{"id":2,"name":"docs"}]}`))
case r.Method == http.MethodPut && r.URL.Path == "/api/v1/repos/alice/project/issues/7/labels":
+2 -8
View File
@@ -6,7 +6,6 @@ package app
import (
"context"
"net/http"
"regexp"
"strconv"
"testing"
"time"
@@ -107,7 +106,7 @@ func TestIssueListTables(t *testing.T) {
}))
defer server.Close()
deps, out, diagnostics := serverDeps(t, server.URL)
deps.Now = func() time.Time { return time.Date(2026, 10, 11, 20, 0, 0, 0, time.UTC) }
deps.Now = func() time.Time { return testNow }
args := []string{"issue", "list", "-R", "alice/project", "-L", "3"}
require.NoError(t, Execute(context.Background(), deps, args))
require.Equal(t, "7\tShort\tbug, priority/high\topen\tissue\talice\t2026-10-11T18:00:00Z\n"+
@@ -131,7 +130,7 @@ func TestIssueListTables(t *testing.T) {
out.Reset()
deps.Streams.OutTTY = true
require.NoError(t, Execute(context.Background(), deps, append(append(args, test.args...), "--no-input")))
require.Equal(t, test.want, stripLinks(stripColors(out.String())))
require.Equal(t, test.want, stripLinks(withoutANSI(out.String())))
}
require.Contains(t, out.String(), "\x1b]8;;https://example.org/i/7\x1b\\\x1b[32m#7\x1b[0m\x1b]8;;\x1b\\")
require.Contains(t, out.String(), "\x1b[35mmerged\x1b[0m")
@@ -158,11 +157,6 @@ func TestIssueListWebOpensTheFilteredPage(t *testing.T) {
require.Equal(t, server.URL+"/alice/project/issues?q=login+bug&state=closed", browser.resource)
}
// stripColors removes SGR color sequences from rendered output.
func stripColors(s string) string {
return regexp.MustCompile("\x1b\\[[0-9;]*m").ReplaceAllString(s, "")
}
func TestIssueListKindFilter(t *testing.T) {
var seen string
server := newAuthenticatedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+1 -1
View File
@@ -17,7 +17,7 @@ func TestIssueCreationMetadataAndReferenceClearing(t *testing.T) {
calls := 0
server := newAuthenticatedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path == "/api/v1/repos/owner/repo/milestones" {
writeMilestones(w, r, `[{"id":4,"title":"Release"}]`)
writeFirstPage(w, r, `[{"id":4,"title":"Release"}]`)
return
}
calls++
+1 -5
View File
@@ -96,11 +96,7 @@ func TestLabelsByName(t *testing.T) {
server := newAuthenticatedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch r.Method + " " + r.URL.Path {
case "GET /api/v1/repos/alice/project/labels":
if r.URL.Query().Get("page") != "1" {
_, _ = w.Write([]byte(`[]`))
return
}
_, _ = w.Write([]byte(labels))
writeFirstPage(w, r, labels)
default:
changed = append(changed, r.Method+" "+r.URL.Path+" "+requestFields(t, r, "name", "color", "description"))
if r.Method == http.MethodDelete {
+1 -1
View File
@@ -18,7 +18,7 @@ func TestBulkMilestoneStateContinuesAfterFailureAndKeepsJSONClean(t *testing.T)
mutations := []string{}
server := newAuthenticatedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path == "/api/v1/repos/alice/project/milestones" {
writeMilestones(w, r, `[{"id":9,"title":"v9"},{"id":10,"title":"v10"},{"id":11,"title":"v11"}]`)
writeFirstPage(w, r, `[{"id":9,"title":"v9"},{"id":10,"title":"v10"},{"id":11,"title":"v11"}]`)
return
}
id := strings.TrimPrefix(r.URL.Path, "/api/v1/repos/alice/project/milestones/")
+3 -3
View File
@@ -74,7 +74,7 @@ func TestMilestoneTablesViewsAndDoneLines(t *testing.T) {
server := newAuthenticatedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch r.Method + " " + r.URL.Path {
case "GET /api/v1/repos/alice/project/milestones":
writeMilestones(w, r, `[{"id":5,"title":"later","state":"open"},{"id":4,"title":"v0.9","state":"closed","closed_issues":3},`+
writeFirstPage(w, r, `[{"id":5,"title":"later","state":"open"},{"id":4,"title":"v0.9","state":"closed","closed_issues":3},`+
`{"id":3,"title":"v1.0","state":"open","description":"First release","due_on":"2026-12-31T00:00:00Z","open_issues":3,"closed_issues":1}]`)
case "GET /api/v1/repos/alice/project/issues/1", "GET /api/v1/repos/alice/project/issues/2":
_, _ = w.Write([]byte(`{"number":1,"milestone":{"id":4,"title":"v0.9"}}`))
@@ -88,7 +88,7 @@ func TestMilestoneTablesViewsAndDoneLines(t *testing.T) {
}))
defer server.Close()
deps, out, diagnostics := serverDeps(t, server.URL)
deps.Now = func() time.Time { return time.Date(2026, 10, 11, 20, 0, 0, 0, time.UTC) }
deps.Now = func() time.Time { return testNow }
deps.Getenv = serverEnv(server.URL, map[string]string{"NO_COLOR": "1"})
plainOutput(t, deps)
run := func(tty bool, args ...string) {
@@ -132,7 +132,7 @@ func TestMilestoneEditFormStartsFromTheMilestone(t *testing.T) {
server := newAuthenticatedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch r.Method + " " + r.URL.Path {
case "GET /api/v1/repos/alice/project/milestones":
writeMilestones(w, r, `[{"id":3,"title":"v1.0","description":"First","due_on":"2026-12-31T00:00:00Z"}]`)
writeFirstPage(w, r, `[{"id":3,"title":"v1.0","description":"First","due_on":"2026-12-31T00:00:00Z"}]`)
case "PATCH /api/v1/repos/alice/project/milestones/3":
require.NoError(t, json.NewDecoder(r.Body).Decode(&edited))
_, _ = w.Write([]byte(`{"id":3,"title":"v1.0.0"}`))
+1 -1
View File
@@ -44,7 +44,7 @@ func TestMilestoneEditEditorSeedsDescription(t *testing.T) {
server := newAuthenticatedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch {
case r.Method == http.MethodGet && r.URL.Path == "/api/v1/repos/alice/project/milestones":
writeMilestones(w, r, `[{"id":4,"title":"Ship","description":"current notes","state":"open"}]`)
writeFirstPage(w, r, `[{"id":4,"title":"Ship","description":"current notes","state":"open"}]`)
case r.Method == http.MethodGet && r.URL.Path == "/api/v1/repos/alice/project/milestones/4":
_, _ = w.Write([]byte(`{"id":4,"title":"Ship","description":"current notes","state":"open"}`))
case r.Method == http.MethodPatch && r.URL.Path == "/api/v1/repos/alice/project/milestones/4":
+2 -10
View File
@@ -62,7 +62,7 @@ func TestMilestoneDeleteReturnsJSONSnapshotOnlyAfterSuccess(t *testing.T) {
calls = append(calls, r.Method)
if r.Method == http.MethodGet {
require.Equal(t, "/api/v1/repos/alice/project/milestones", r.URL.Path)
writeMilestones(w, r, `[{"id":9,"title":"Release one","state":"open"}]`)
writeFirstPage(w, r, `[{"id":9,"title":"Release one","state":"open"}]`)
return
}
require.Equal(t, "/api/v1/repos/alice/project/milestones/9", r.URL.Path)
@@ -118,14 +118,6 @@ func TestMilestoneIssueCommandsSelectByName(t *testing.T) {
require.ErrorContains(t, err, "milestone title or ID cannot be empty")
}
// writeMilestones answers a milestone listing with page, a JSON array, as its first and only page.
func writeMilestones(w http.ResponseWriter, r *http.Request, page string) {
if r.URL.Query().Get("page") != "1" {
page = `[]`
}
_, _ = w.Write([]byte(page))
}
// payloadField returns the JSON request body's field name as text.
func payloadField(t *testing.T, r *http.Request, name string) string {
t.Helper()
@@ -139,7 +131,7 @@ func TestMilestonesAcceptTitlesOrIDs(t *testing.T) {
server := newAuthenticatedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch r.Method + " " + r.URL.Path {
case "GET /api/v1/repos/alice/project/milestones":
writeMilestones(w, r, `[{"id":3,"title":"v1.0","state":"open"},{"id":4,"title":"2026","state":"closed"},{"id":5,"title":"v2.0"}]`)
writeFirstPage(w, r, `[{"id":3,"title":"v1.0","state":"open"},{"id":4,"title":"2026","state":"closed"},{"id":5,"title":"v2.0"}]`)
case "GET /api/v1/repos/alice/project/milestones/3", "GET /api/v1/repos/alice/project/milestones/4":
_, _ = w.Write([]byte(`{"id":3,"title":"v1.0","state":"open"}`))
case "PATCH /api/v1/repos/alice/project/milestones/3", "PATCH /api/v1/repos/alice/project/milestones/4":
+1 -1
View File
@@ -68,7 +68,7 @@ func TestNotificationsListTheInboxByDefault(t *testing.T) {
}
deps, out, _ := serverDeps(t, server.URL)
deps.Streams.OutTTY, deps.Streams.Width = true, 100
deps.Now = func() time.Time { return time.Date(2026, 10, 11, 20, 0, 0, 0, time.UTC) }
deps.Now = func() time.Time { return testNow }
require.NoError(t, Execute(context.Background(), deps, []string{"notification", "list"}))
require.Equal(t, `Showing 2 of 2 unread or pinned notifications in your inbox
+1 -5
View File
@@ -48,11 +48,7 @@ func TestPullDiffColorsHeadersAndHunks(t *testing.T) {
func TestPullDiffNameOnly(t *testing.T) {
server := newAuthenticatedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
require.Equal(t, "/api/v1/repos/alice/project/pulls/2/files", r.URL.Path)
if r.URL.Query().Get("page") != "1" {
_, _ = w.Write([]byte(`[]`))
return
}
_, _ = w.Write([]byte(`[{"filename":"one.txt"},{"filename":"docs/two.md"}]`))
writeFirstPage(w, r, `[{"filename":"one.txt"},{"filename":"docs/two.md"}]`)
}))
defer server.Close()
deps, out, _ := serverDeps(t, server.URL)
+2 -6
View File
@@ -64,17 +64,13 @@ func refApplication(t *testing.T, gitResults map[string]string) (*application, s
t.Helper()
server := newAuthenticatedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
require.Equal(t, "/api/v1/repos/alice/project/pulls", r.URL.Path)
if r.URL.Query().Get("page") != "1" {
_, _ = w.Write([]byte(`[]`))
return
}
_, _ = w.Write([]byte(`[
writeFirstPage(w, r, `[
{"number":3,"head":{"ref":"feat/one","repo":{"full_name":"alice/project"}}},
{"number":4,"head":{"ref":"feat/two","repo":{"full_name":"alice/project"}}},
{"number":17,"head":{"ref":"fix","repo":{"full_name":"bob/project"}}},
{"number":20,"head":{"ref":"dup","repo":{"full_name":"alice/project"}}},
{"number":21,"head":{"ref":"dup","repo":{"full_name":"carol/project"}}}
]`))
]`)
}))
t.Cleanup(server.Close)
deps, _, _ := testDeps(t)
+1 -5
View File
@@ -151,11 +151,7 @@ func TestRepoForkReportsAnExistingFork(t *testing.T) {
w.WriteHeader(http.StatusConflict)
_, _ = w.Write([]byte(`{"message":"repository is already forked by user [uname: alice, repo path: bob/project, fork path: alice/project-fork]"}`))
case "GET /api/v1/repos/bob/project/forks":
if r.URL.Query().Get("page") != "1" {
_, _ = w.Write([]byte(`[]`))
return
}
_, _ = w.Write([]byte(`[{"full_name":"carol/project","owner":{"login":"carol"}},{"full_name":"alice/project-fork","owner":{"login":"alice"}}]`))
writeFirstPage(w, r, `[{"full_name":"carol/project","owner":{"login":"carol"}},{"full_name":"alice/project-fork","owner":{"login":"alice"}}]`)
case "GET /api/v1/repos/alice/project-fork":
_, _ = w.Write([]byte(`{"full_name":"alice/project-fork","fork":true,"html_url":"https://gitea.test/alice/project-fork","parent":{"full_name":"bob/project"}}`))
default:
+1 -1
View File
@@ -21,7 +21,7 @@ func repoTTYDeps(t *testing.T, serverURL string) (Dependencies, *bytes.Buffer, *
deps, out, diagnostics := serverDeps(t, serverURL)
deps.Getenv = serverEnv(serverURL, map[string]string{"TERM": "dumb"})
deps.Streams.OutTTY, deps.Streams.Width = true, 100
deps.Now = func() time.Time { return time.Date(2026, 10, 11, 20, 0, 0, 0, time.UTC) }
deps.Now = func() time.Time { return testNow }
return deps, out, diagnostics
}
+3 -7
View File
@@ -64,12 +64,8 @@ func TestTimeTablesAndDoneLines(t *testing.T) {
server := newAuthenticatedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch r.Method + " " + r.URL.Path {
case "GET /api/v1/repos/alice/project/times", "GET /api/v1/repos/alice/project/issues/1/times":
if r.URL.Query().Get("page") != "1" {
_, _ = w.Write([]byte(`[]`))
return
}
_, _ = w.Write([]byte(`[{"id":8,"time":5400,"created":"2026-10-11T18:00:00Z","user_name":"alice","issue":{"number":1,"title":"Login fails","repository":{"full_name":"alice/project"}}},` +
`{"id":9,"time":900,"created":"2026-10-11T19:00:00Z","user_name":"bob","issue":{"number":2,"title":"Docs"}}]`))
writeFirstPage(w, r, `[{"id":8,"time":5400,"created":"2026-10-11T18:00:00Z","user_name":"alice","issue":{"number":1,"title":"Login fails","repository":{"full_name":"alice/project"}}},`+
`{"id":9,"time":900,"created":"2026-10-11T19:00:00Z","user_name":"bob","issue":{"number":2,"title":"Docs"}}]`)
case "POST /api/v1/repos/alice/project/issues/1/times":
changed = append(changed, r.Method+" "+r.URL.Path)
_, _ = w.Write([]byte(`{"id":10,"time":5100,"user_name":"alice","issue":{"number":1,"title":"Login fails"}}`))
@@ -80,7 +76,7 @@ func TestTimeTablesAndDoneLines(t *testing.T) {
}))
defer server.Close()
deps, out, diagnostics := serverDeps(t, server.URL)
deps.Now = func() time.Time { return time.Date(2026, 10, 11, 20, 0, 0, 0, time.UTC) }
deps.Now = func() time.Time { return testNow }
deps.Getenv = serverEnv(server.URL, map[string]string{"NO_COLOR": "1"})
deps.Streams.OutTTY = true
run := func(args ...string) error {
+1 -5
View File
@@ -34,11 +34,7 @@ func TestWikiEditRenamesAndKeepsTheContent(t *testing.T) {
func TestWikiListLimitsPagesOnTheClient(t *testing.T) {
server := newAuthenticatedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Query().Get("page") != "1" {
_, _ = w.Write([]byte(`[]`))
return
}
_, _ = w.Write([]byte(`[{"title":"Getting Started","last_commit":{"author":{"name":"alice","date":"2026-10-11T18:00:00Z"}}},{"title":"Home"}]`))
writeFirstPage(w, r, `[{"title":"Getting Started","last_commit":{"author":{"name":"alice","date":"2026-10-11T18:00:00Z"}}},{"title":"Home"}]`)
}))
defer server.Close()
deps, out, _ := repoTTYDeps(t, server.URL)
+8
View File
@@ -75,3 +75,11 @@ func TestNameOrIDPrefersIDsThenExactThenFoldedNames(t *testing.T) {
require.Equal(t, tc.want, got.id, tc.raw)
}
}
// writeFirstPage answers the first page of a listing with page and every later page with [].
func writeFirstPage(w http.ResponseWriter, r *http.Request, page string) {
if r.URL.Query().Get("page") != "1" {
page = `[]`
}
_, _ = w.Write([]byte(page))
}
+1 -5
View File
@@ -76,11 +76,7 @@ func TestWikiListAndRevisionsMapCommits(t *testing.T) {
switch r.URL.Path {
case "/api/v1/repos/alice/project/wiki/pages":
assert.Equal(t, "50", r.URL.Query().Get("limit"))
if r.URL.Query().Get("page") != "1" {
_, _ = w.Write([]byte(`[]`))
return
}
_, _ = w.Write([]byte(`[{"title":"Other"},{"title":"Home","html_url":"https://gitea.test/wiki/Home","last_commit":{"sha":"abc","author":{"name":"Alice","email":"author@example.test","date":"2026-10-04T00:00:00Z"}}},{"title":"Draft"}]`))
writeFirstPage(w, r, `[{"title":"Other"},{"title":"Home","html_url":"https://gitea.test/wiki/Home","last_commit":{"sha":"abc","author":{"name":"Alice","email":"author@example.test","date":"2026-10-04T00:00:00Z"}}},{"title":"Draft"}]`)
case "/api/v1/repos/alice/project/wiki/revisions/Home":
assert.Equal(t, "3", r.URL.Query().Get("page"))
_, _ = w.Write([]byte(`{"commits":[{"sha":"abc","message":"Edit","author":{"name":"Alice","email":"author@example.test","date":"2026-10-04T00:00:00Z"}},{"sha":"def","author":null}],"count":2}`))