mirror of
https://gitea.com/gitea/tea.git
synced 2026-10-26 11:01:25 +01:00
refactor: reuse the existing service and rendering helpers
services.IsNotFound replaces the hand-rolled 404 checks, convertPage the copied page conversions and lastPathNumber the comment's own number parser. The List wrappers around ListPage of releases, branches, wiki pages, secrets and variables go, pull request filters resolve milestones through Milestones.FindOne like issues, and localFlagsChanged, boolOrder, Cell.Render, stateBadge and dueText replace their copies. Signed-off-by: bircni <bircni@icloud.com>
This commit is contained in:
33 files changed
+85
-212
No files matched your search
@@ -82,7 +82,7 @@ func (s Actions) JobsPage(ctx context.Context, run int64, limit, page int) (Page
|
||||
if err != nil {
|
||||
return Page[Job]{}, err
|
||||
}
|
||||
return Page[Job]{Items: convertAll(window.Items, jobFrom), More: window.More, Total: window.Total, Counted: window.Counted}, nil
|
||||
return convertPage(window, jobFrom), nil
|
||||
}
|
||||
|
||||
// WaitForFirstJob polls a freshly dispatched run until the server has created its first job.
|
||||
|
||||
@@ -63,13 +63,7 @@ type ActionSecrets struct {
|
||||
Scope ActionScope
|
||||
}
|
||||
|
||||
// List returns secret metadata only.
|
||||
func (s ActionSecrets) List(ctx context.Context, limit, page int) ([]ActionSecret, error) {
|
||||
window, err := s.ListPage(ctx, limit, page)
|
||||
return window.Items, err
|
||||
}
|
||||
|
||||
// ListPage is List with what the server reports about the other pages.
|
||||
// ListPage lists a page of secrets, with what the server reports about the other pages.
|
||||
func (s ActionSecrets) ListPage(ctx context.Context, limit, page int) (Page[ActionSecret], error) {
|
||||
if s.Scope.Account {
|
||||
return Page[ActionSecret]{}, &CapabilityError{Feature: "account secret listing", Reason: "Gitea exposes account secret set/delete operations only"}
|
||||
@@ -88,7 +82,7 @@ func (s ActionSecrets) ListPage(ctx context.Context, limit, page int) (Page[Acti
|
||||
})
|
||||
return secrets, headerOf(resp), err
|
||||
})
|
||||
return Page[ActionSecret]{Items: convertAll(window.Items, secretFrom), More: window.More, Total: window.Total, Counted: window.Counted}, err
|
||||
return convertPage(window, secretFrom), err
|
||||
}
|
||||
|
||||
// Set creates or replaces a secret; the API's PUT operation defines upsert semantics. The result
|
||||
@@ -147,13 +141,7 @@ func (s ActionVariables) repoVariables(name string) string {
|
||||
return endpoint
|
||||
}
|
||||
|
||||
// List returns a non-nil page of variables.
|
||||
func (s ActionVariables) List(ctx context.Context, limit, page int) ([]ActionVariable, error) {
|
||||
window, err := s.ListPage(ctx, limit, page)
|
||||
return window.Items, err
|
||||
}
|
||||
|
||||
// ListPage is List with what the server reports about the other pages.
|
||||
// ListPage lists a page of variables, with what the server reports about the other pages.
|
||||
func (s ActionVariables) ListPage(ctx context.Context, limit, page int) (Page[ActionVariable], error) {
|
||||
var window Page[*gitea.ActionsVariable]
|
||||
var err error
|
||||
@@ -170,7 +158,7 @@ func (s ActionVariables) ListPage(ctx context.Context, limit, page int) (Page[Ac
|
||||
} else {
|
||||
window, err = rawPage[*gitea.ActionsVariable](ctx, s.Client, s.repoVariables(""), nil, limit, page)
|
||||
}
|
||||
return Page[ActionVariable]{Items: convertAll(window.Items, variableFrom), More: window.More, Total: window.Total, Counted: window.Counted}, err
|
||||
return convertPage(window, variableFrom), err
|
||||
}
|
||||
|
||||
// View retrieves one variable.
|
||||
|
||||
@@ -82,9 +82,9 @@ func TestVariableReadsAndDeletesUseTheirScope(t *testing.T) {
|
||||
}))
|
||||
service := ActionVariables{Client: client, Scope: scope.scope}
|
||||
want := ActionVariable{Name: "MODE", Value: "test", Description: "build mode"}
|
||||
items, err := service.List(context.Background(), 20, 2)
|
||||
items, err := service.ListPage(context.Background(), 20, 2)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, []ActionVariable{want}, items)
|
||||
require.Equal(t, []ActionVariable{want}, items.Items)
|
||||
item, err := service.View(context.Background(), "MODE")
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, want, item)
|
||||
@@ -128,14 +128,14 @@ func TestSecretListReturnsMetadataOnly(t *testing.T) {
|
||||
assert.Equal(t, "2", r.URL.Query().Get("page"))
|
||||
_, _ = w.Write([]byte(`[{"name":"TOKEN","data":"never-display","description":"deploy","created_at":"2028-01-02T03:04:05Z"},{"name":"OTHER"}]`))
|
||||
}))
|
||||
items, err := (ActionSecrets{Client: client, Scope: scope.scope}).List(context.Background(), 20, 2)
|
||||
items, err := (ActionSecrets{Client: client, Scope: scope.scope}).ListPage(context.Background(), 20, 2)
|
||||
if scope.scope.Account {
|
||||
var unsupported *CapabilityError
|
||||
require.ErrorAs(t, err, &unsupported)
|
||||
return
|
||||
}
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, []ActionSecret{{Name: "TOKEN", Description: "deploy", CreatedAt: "2028-01-02T03:04:05Z"}, {Name: "OTHER"}}, items)
|
||||
require.Equal(t, []ActionSecret{{Name: "TOKEN", Description: "deploy", CreatedAt: "2028-01-02T03:04:05Z"}, {Name: "OTHER"}}, items.Items)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -39,13 +39,7 @@ func branchFrom(branch *gitea.Branch) Branch {
|
||||
// Branches operates on remote branches and protection rules.
|
||||
type Branches struct{ Client *transport.Client }
|
||||
|
||||
// List returns a page of remote branches.
|
||||
func (s Branches) List(ctx context.Context, repo string, limit, page int) ([]Branch, error) {
|
||||
window, err := s.ListPage(ctx, repo, limit, page)
|
||||
return window.Items, err
|
||||
}
|
||||
|
||||
// ListPage is List that also reports whether more branches follow and how many there are.
|
||||
// ListPage lists a page of branches, with whether more follow and how many there are.
|
||||
func (s Branches) ListPage(ctx context.Context, repo string, limit, page int) (Page[Branch], error) {
|
||||
window, err := listPage(limit, page, func(limit, page int) ([]*gitea.Branch, http.Header, error) {
|
||||
var headers http.Header
|
||||
@@ -59,7 +53,7 @@ func (s Branches) ListPage(ctx context.Context, repo string, limit, page int) (P
|
||||
if err != nil {
|
||||
return Page[Branch]{}, err
|
||||
}
|
||||
return Page[Branch]{Items: convertAll(window.Items, branchFrom), More: window.More, Total: window.Total, Counted: window.Counted}, nil
|
||||
return convertPage(window, branchFrom), nil
|
||||
}
|
||||
|
||||
// View retrieves a remote branch.
|
||||
@@ -143,7 +137,7 @@ func (s Branches) Unprotect(ctx context.Context, repo, rule string) (bool, error
|
||||
err := repoDo(ctx, s.Client, repo, func(ctx context.Context, c *gitea.Client, owner, name string) (*gitea.Response, error) {
|
||||
return c.Repositories.DeleteBranchProtection(ctx, owner, name, rule)
|
||||
})
|
||||
if apiErr, ok := errors.AsType[*transport.APIError](err); ok && apiErr.Status == http.StatusNotFound {
|
||||
if IsNotFound(err) {
|
||||
if _, err := (Repositories{Client: s.Client}).get(ctx, repo); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
@@ -36,12 +36,12 @@ func TestBranchListMapsServerFields(t *testing.T) {
|
||||
assert.Equal(t, "3", r.URL.Query().Get("page"))
|
||||
_, _ = w.Write([]byte(`[{"name":"main","commit":{"id":"abc","message":"Fix\n\nbody","timestamp":"2026-10-01T12:00:00Z"},"protected":true,"required_approvals":2,"user_can_push":true,"user_can_merge":true},{"name":"orphan","commit":null}]`))
|
||||
}))
|
||||
items, err := (Branches{Client: client}).List(context.Background(), "owner/repo", 20, 3)
|
||||
items, err := (Branches{Client: client}).ListPage(context.Background(), "owner/repo", 20, 3)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, []Branch{
|
||||
{Name: "main", SHA: "abc", Message: "Fix\n\nbody", UpdatedAt: "2026-10-01T12:00:00Z", Protected: true, RequiredApprovals: 2, CanPush: true, CanMerge: true},
|
||||
{Name: "orphan"},
|
||||
}, items)
|
||||
}, items.Items)
|
||||
}
|
||||
|
||||
func TestBranchCreateAndProtectPayloads(t *testing.T) {
|
||||
|
||||
@@ -5,7 +5,6 @@ package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
"path"
|
||||
"strconv"
|
||||
|
||||
gitea "gitea.dev/sdk"
|
||||
@@ -30,19 +29,10 @@ func commentFrom(comment *gitea.Comment) Comment {
|
||||
return Comment{
|
||||
ID: comment.ID, Body: comment.Body, URL: comment.HTMLURL, Author: login(comment.Poster),
|
||||
CreatedAt: timestamp(comment.Created), UpdatedAt: timestamp(comment.Updated), Pull: comment.PRURL != "",
|
||||
IssueNumber: discussionNumber(comment.IssueURL + comment.PRURL),
|
||||
IssueNumber: lastPathNumber(comment.IssueURL + comment.PRURL),
|
||||
}
|
||||
}
|
||||
|
||||
// discussionNumber reads the number from the web URL of an issue or pull request, or returns 0.
|
||||
func discussionNumber(url string) int64 {
|
||||
n, err := strconv.ParseInt(path.Base(url), 10, 64)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
// Comments implements discussion comments under their owning repository resource.
|
||||
type Comments struct {
|
||||
Client *transport.Client
|
||||
|
||||
@@ -66,3 +66,8 @@ func issueFrom(issue *gitea.Issue) Issue {
|
||||
Assignees: convertAll(issue.Assignees, login), Milestone: issueMilestoneFrom(issue.Milestone), Comments: int64(issue.Comments),
|
||||
}
|
||||
}
|
||||
|
||||
// convertPage maps a page of SDK items onto tea results.
|
||||
func convertPage[S, T any](page Page[*S], convert func(*S) T) Page[T] {
|
||||
return Page[T]{Items: convertAll(page.Items, convert), More: page.More, Total: page.Total, Counted: page.Counted}
|
||||
}
|
||||
@@ -194,6 +194,12 @@ func Classify(err error, kind, key, scope string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// IsNotFound reports whether err is a 404 response.
|
||||
func IsNotFound(err error) bool {
|
||||
failure, ok := errors.AsType[*transport.APIError](err)
|
||||
return ok && failure.Status == http.StatusNotFound
|
||||
}
|
||||
|
||||
// refusal returns the conflict reason of a refused request, or "".
|
||||
func refusal(apiErr *transport.APIError) string {
|
||||
if apiErr.Status == http.StatusLocked {
|
||||
|
||||
@@ -5,11 +5,8 @@ package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
gitea "gitea.dev/sdk"
|
||||
"gitea.dev/tea/internal/transport"
|
||||
)
|
||||
|
||||
// IssueReference identifies an issue that may live in another repository.
|
||||
@@ -57,7 +54,7 @@ func (s Issues) Dependencies(ctx context.Context, number int64) (IssueDependenci
|
||||
})
|
||||
return convertAll(issues, issueReferenceFrom), err
|
||||
})
|
||||
if api, ok := errors.AsType[*transport.APIError](err); ok && api.Status == http.StatusNotFound {
|
||||
if IsNotFound(err) {
|
||||
return IssueDependencies{}, nil
|
||||
}
|
||||
if err != nil {
|
||||
|
||||
@@ -132,7 +132,7 @@ func (s Issues) ListPage(ctx context.Context, opts ListOptions) (Page[Issue], er
|
||||
if err != nil {
|
||||
return Page[Issue]{}, err
|
||||
}
|
||||
return Page[Issue]{Items: convertAll(issues.Items, discussionFrom), More: issues.More, Total: issues.Total, Counted: issues.Counted}, nil
|
||||
return convertPage(issues, discussionFrom), nil
|
||||
}
|
||||
|
||||
// filterValues splits a comma-separated filter, which the SDK joins again.
|
||||
|
||||
@@ -58,7 +58,7 @@ func (s Labels) ListPage(ctx context.Context, limit, page int) (Page[Label], err
|
||||
labels, resp, err := s.list(ctx, limit, page)
|
||||
return labels, headerOf(resp), err
|
||||
})
|
||||
return Page[Label]{Items: convertAll(labels.Items, labelFrom), More: labels.More, Total: labels.Total, Counted: labels.Counted}, err
|
||||
return convertPage(labels, labelFrom), err
|
||||
}
|
||||
|
||||
func (s Labels) list(ctx context.Context, limit, page int) ([]*gitea.Label, *gitea.Response, error) {
|
||||
@@ -218,7 +218,7 @@ func (s Milestones) ListPage(ctx context.Context, state string, limit, page int)
|
||||
})
|
||||
return milestones, headerOf(resp), err
|
||||
})
|
||||
return Page[Milestone]{Items: convertAll(milestones.Items, milestoneFrom), More: milestones.More, Total: milestones.Total, Counted: milestones.Counted}, err
|
||||
return convertPage(milestones, milestoneFrom), err
|
||||
}
|
||||
|
||||
// Create creates one milestone.
|
||||
|
||||
@@ -5,36 +5,9 @@ package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ResolveName selects an exact title across open and closed milestones.
|
||||
func (s Milestones) ResolveName(ctx context.Context, name string) (int64, error) {
|
||||
if strings.TrimSpace(name) == "" {
|
||||
return 0, fmt.Errorf("milestone name cannot be empty")
|
||||
}
|
||||
items, err := s.All(ctx)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
var id int64
|
||||
for _, item := range items {
|
||||
if item.Title != name {
|
||||
continue
|
||||
}
|
||||
if id != 0 {
|
||||
return 0, fmt.Errorf("milestone name %q is ambiguous; select its numeric ID", name)
|
||||
}
|
||||
id = item.ID
|
||||
}
|
||||
if id == 0 {
|
||||
return 0, fmt.Errorf("milestone %q does not exist; use tea milestone list --state all", name)
|
||||
}
|
||||
return id, nil
|
||||
}
|
||||
|
||||
// All returns the open and closed milestones of the repository.
|
||||
func (s Milestones) All(ctx context.Context) ([]Milestone, error) {
|
||||
return listAll(func(page int) ([]Milestone, error) { return s.List(ctx, "all", 100, page) })
|
||||
|
||||
@@ -32,12 +32,12 @@ func TestMilestoneNamesIncludeClosedAndRejectAmbiguity(t *testing.T) {
|
||||
}
|
||||
}))
|
||||
service := Milestones{Client: client, Repository: "alice/project"}
|
||||
id, err := service.ResolveName(context.Background(), "Release")
|
||||
item, err := service.FindOne(context.Background(), "Release", false)
|
||||
require.NoError(t, err)
|
||||
require.EqualValues(t, 2, id)
|
||||
_, err = service.ResolveName(context.Background(), "missing")
|
||||
require.ErrorContains(t, err, "does not exist")
|
||||
require.EqualValues(t, 2, item.ID)
|
||||
_, err = service.FindOne(context.Background(), "missing", false)
|
||||
require.ErrorContains(t, err, "not found")
|
||||
duplicate = true
|
||||
_, err = service.ResolveName(context.Background(), "Release")
|
||||
_, err = service.FindOne(context.Background(), "Release", false)
|
||||
require.ErrorContains(t, err, "ambiguous")
|
||||
}
|
||||
@@ -34,7 +34,7 @@ func organization(ctx context.Context, client *transport.Client, owner string) (
|
||||
org, _, err := call(ctx, client, func(ctx context.Context, c *gitea.Client) (*gitea.Organization, *gitea.Response, error) {
|
||||
return c.Organizations.GetOrg(ctx, owner)
|
||||
})
|
||||
if statusNotFound(err) {
|
||||
if IsNotFound(err) {
|
||||
return 0, false, nil
|
||||
}
|
||||
if err != nil {
|
||||
@@ -46,12 +46,6 @@ func organization(ctx context.Context, client *transport.Client, owner string) (
|
||||
return org.ID, true, nil
|
||||
}
|
||||
|
||||
// statusNotFound reports whether err is a 404 response.
|
||||
func statusNotFound(err error) bool {
|
||||
failure, ok := errors.AsType[*transport.APIError](err)
|
||||
return ok && failure.Status == http.StatusNotFound
|
||||
}
|
||||
|
||||
// OrganizationOptions permits explicit empty and false preference updates.
|
||||
type OrganizationOptions struct {
|
||||
Name *string `json:"username,omitempty"`
|
||||
@@ -84,11 +78,6 @@ func (s Organizations) List(ctx context.Context, mine bool, username string, lim
|
||||
return convertPage(orgs, organizationFrom), err
|
||||
}
|
||||
|
||||
// convertPage maps a page of SDK items onto tea results.
|
||||
func convertPage[S, T any](page Page[*S], convert func(*S) T) Page[T] {
|
||||
return Page[T]{Items: convertAll(page.Items, convert), More: page.More, Total: page.Total, Counted: page.Counted}
|
||||
}
|
||||
|
||||
// View retrieves a named organization.
|
||||
func (s Organizations) View(ctx context.Context, name string) (Organization, error) {
|
||||
org, _, err := call(ctx, s.Client, func(ctx context.Context, c *gitea.Client) (*gitea.Organization, *gitea.Response, error) {
|
||||
@@ -285,7 +274,7 @@ func (s Organizations) IsPublicMember(ctx context.Context, name, username string
|
||||
// check runs a membership check that answers no with a 404.
|
||||
func (s Organizations) check(ctx context.Context, op func(context.Context, *gitea.Client) (*gitea.Response, error)) (bool, error) {
|
||||
err := do(ctx, s.Client, op)
|
||||
if statusNotFound(err) {
|
||||
if IsNotFound(err) {
|
||||
return false, nil
|
||||
}
|
||||
return err == nil, err
|
||||
|
||||
@@ -224,7 +224,7 @@ func (s Pulls) listPage(ctx context.Context, options PullListOptions) (Page[Pull
|
||||
if err != nil {
|
||||
return Page[Pull]{}, err
|
||||
}
|
||||
return Page[Pull]{Items: convertAll(page.Items, pullFrom), More: page.More, Total: page.Total, Counted: page.Counted}, nil
|
||||
return convertPage(page, pullFrom), nil
|
||||
}
|
||||
|
||||
// View retrieves one pull request.
|
||||
@@ -476,7 +476,7 @@ func (s Pulls) Template(ctx context.Context, ref string) (string, error) {
|
||||
return c.Repositories.GetFileReader(ctx, owner, name, ref, path)
|
||||
})
|
||||
if err != nil {
|
||||
if apiError, ok := errors.AsType[*transport.APIError](err); ok && apiError.Status == http.StatusNotFound {
|
||||
if IsNotFound(err) {
|
||||
continue
|
||||
}
|
||||
return "", err
|
||||
|
||||
@@ -55,13 +55,7 @@ type Releases struct {
|
||||
|
||||
func (s Releases) endpoint() string { return "repos/" + s.Repository + "/releases" }
|
||||
|
||||
// List returns a non-nil page of releases.
|
||||
func (s Releases) List(ctx context.Context, limit, page int) ([]Release, error) {
|
||||
window, err := s.ListPage(ctx, limit, page)
|
||||
return window.Items, err
|
||||
}
|
||||
|
||||
// ListPage is List that also reports whether more releases follow and how many there are.
|
||||
// ListPage lists a page of releases, with whether more follow and how many there are.
|
||||
func (s Releases) ListPage(ctx context.Context, limit, page int) (Page[Release], error) {
|
||||
window, err := listPage(limit, page, func(limit, page int) ([]*gitea.Release, http.Header, error) {
|
||||
var headers http.Header
|
||||
@@ -75,7 +69,7 @@ func (s Releases) ListPage(ctx context.Context, limit, page int) (Page[Release],
|
||||
if err != nil {
|
||||
return Page[Release]{}, err
|
||||
}
|
||||
return Page[Release]{Items: convertAll(window.Items, releaseFrom), More: window.More, Total: window.Total, Counted: window.Counted}, nil
|
||||
return convertPage(window, releaseFrom), nil
|
||||
}
|
||||
|
||||
// View retrieves a release by its tag, including numeric tags.
|
||||
|
||||
@@ -171,9 +171,9 @@ func TestReleaseListAndViewEscapeTags(t *testing.T) {
|
||||
_, _ = w.Write([]byte(`{"id":2,"tag_name":"v1/beta one"}`))
|
||||
}))
|
||||
service := Releases{Client: client, Repository: "alice/project"}
|
||||
items, err := service.List(context.Background(), 10, 2)
|
||||
items, err := service.ListPage(context.Background(), 10, 2)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, []Release{{ID: 1, Tag: "v1", Assets: []ReleaseAsset{}}}, items)
|
||||
require.Equal(t, []Release{{ID: 1, Tag: "v1", Assets: []ReleaseAsset{}}}, items.Items)
|
||||
item, err := service.View(context.Background(), "v1/beta one")
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "v1/beta one", item.Tag)
|
||||
|
||||
@@ -109,7 +109,7 @@ func (s Repositories) Readme(ctx context.Context, repo, ref string) (name, conte
|
||||
return c.Repositories.ListContents(ctx, owner, name, ref, "")
|
||||
})
|
||||
if err != nil {
|
||||
if apiErr, ok := errors.AsType[*transport.APIError](err); ok && apiErr.Status == http.StatusNotFound {
|
||||
if IsNotFound(err) {
|
||||
return "", "", nil
|
||||
}
|
||||
return "", "", err
|
||||
|
||||
@@ -136,5 +136,5 @@ func (s Repositories) Search(ctx context.Context, opts RepositorySearchOptions)
|
||||
if err != nil {
|
||||
return Page[Repository]{}, err
|
||||
}
|
||||
return Page[Repository]{Items: convertAll(window.Items, repositoryFrom), More: window.More, Total: window.Total, Counted: window.Counted}, nil
|
||||
return convertPage(window, repositoryFrom), nil
|
||||
}
|
||||
@@ -6,9 +6,7 @@ package services
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
gitea "gitea.dev/sdk"
|
||||
@@ -81,17 +79,11 @@ func (s Wiki) page(ctx context.Context, op repoOperation[*gitea.WikiPage]) (Wiki
|
||||
return wikiContentFrom(page)
|
||||
}
|
||||
|
||||
// List returns a non-nil page of wiki metadata.
|
||||
func (s Wiki) List(ctx context.Context, limit, page int) ([]WikiPage, error) {
|
||||
window, err := s.ListPage(ctx, limit, page)
|
||||
return window.Items, err
|
||||
}
|
||||
|
||||
// wikiPageSize is the page size for reading the whole wiki; Gitea replaces a limit of 1 with its
|
||||
// default page size.
|
||||
const wikiPageSize = 50
|
||||
|
||||
// ListPage is List that also reports whether more pages follow and how many there are. It reads
|
||||
// ListPage lists a page of wiki pages, with whether more follow and how many there are. It reads
|
||||
// the whole page list and pages it on the client, because the server pages it inconsistently.
|
||||
func (s Wiki) ListPage(ctx context.Context, limit, page int) (Page[WikiPage], error) {
|
||||
all, err := listAll(func(page int) ([]*gitea.WikiPageMetaData, error) {
|
||||
@@ -100,7 +92,7 @@ func (s Wiki) ListPage(ctx context.Context, limit, page int) (Page[WikiPage], er
|
||||
})
|
||||
})
|
||||
if err != nil {
|
||||
if apiError, ok := errors.AsType[*transport.APIError](err); !ok || apiError.Status != http.StatusNotFound {
|
||||
if !IsNotFound(err) {
|
||||
return Page[WikiPage]{}, err
|
||||
}
|
||||
// An uninitialized wiki returns 404. Verify repository visibility and
|
||||
|
||||
@@ -59,14 +59,14 @@ func TestWikiEmptyListDoesNotHideRepositoryErrors(t *testing.T) {
|
||||
}
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
}))
|
||||
items, err := (Wiki{Client: client, Repository: "alice/project"}).List(context.Background(), 30, 1)
|
||||
items, err := (Wiki{Client: client, Repository: "alice/project"}).ListPage(context.Background(), 30, 1)
|
||||
if !wikiEnabled {
|
||||
require.Error(t, err)
|
||||
return
|
||||
}
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, items)
|
||||
require.Empty(t, items)
|
||||
require.NotNil(t, items.Items)
|
||||
require.Empty(t, items.Items)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -95,9 +95,9 @@ func TestWikiListAndRevisionsMapCommits(t *testing.T) {
|
||||
{Title: "Other"},
|
||||
{Title: "Home", URL: "https://gitea.test/wiki/Home", SHA: "abc", Author: "Alice", UpdatedAt: "2026-10-04T00:00:00Z"},
|
||||
}, More: true, Total: 3, Counted: true}, pages)
|
||||
last, err := service.List(context.Background(), 2, 2)
|
||||
last, err := service.ListPage(context.Background(), 2, 2)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, []WikiPage{{Title: "Draft"}}, last)
|
||||
require.Equal(t, []WikiPage{{Title: "Draft"}}, last.Items)
|
||||
revisions, err := service.Revisions(context.Background(), "Home", 3)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, []WikiRevision{{SHA: "abc", Message: "Edit", Author: "Alice", CreatedAt: "2026-10-04T00:00:00Z"}, {SHA: "def"}}, revisions)
|
||||
|
||||
Reference in new issue
Block a user