diff --git a/routers/api/v1/repo/fork.go b/routers/api/v1/repo/fork.go index 8943ad3993..9ca5243631 100644 --- a/routers/api/v1/repo/fork.go +++ b/routers/api/v1/repo/fork.go @@ -55,7 +55,8 @@ func ListForks(ctx *context.APIContext) { // "404": // "$ref": "#/responses/notFound" - forks, total, err := repo_service.FindForks(ctx, ctx.Repo.Repository, ctx.Doer, utils.GetListOptions(ctx)) + listOptions := utils.GetListOptions(ctx) + forks, total, err := repo_service.FindForks(ctx, ctx.Repo.Repository, ctx.Doer, listOptions) if err != nil { ctx.APIErrorInternal(err) return @@ -79,6 +80,7 @@ func ListForks(ctx *context.APIContext) { apiForks[i] = convert.ToRepo(ctx, fork, permission) } + ctx.SetLinkHeader(total, listOptions.PageSize) ctx.SetTotalCountHeader(total) ctx.JSON(http.StatusOK, apiForks) } diff --git a/tests/integration/api_fork_test.go b/tests/integration/api_fork_test.go index cf0a2e4384..4ce2c93428 100644 --- a/tests/integration/api_fork_test.go +++ b/tests/integration/api_fork_test.go @@ -89,7 +89,7 @@ func testAPIForkListLimitedAndPrivateRepos(t *testing.T) { assert.Equal(t, "0", resp.Header().Get("X-Total-Count")) }) - t.Run("Logged in", func(t *testing.T) { + t.Run("LoggedIn", func(t *testing.T) { defer tests.PrintCurrentTest(t)() req := NewRequest(t, "GET", "/api/v1/repos/user2/repo1/forks").AddTokenAuth(user1Token) @@ -107,6 +107,36 @@ func testAPIForkListLimitedAndPrivateRepos(t *testing.T) { assert.Len(t, forks, 2) assert.Equal(t, "2", resp.Header().Get("X-Total-Count")) }) + + t.Run("RespHeaderLinks", func(t *testing.T) { + t.Run("Page1", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + req := NewRequest(t, "GET", "/api/v1/repos/user2/repo1/forks?page=1&limit=1").AddTokenAuth(user1Token) + resp := MakeRequest(t, req, http.StatusOK) + assert.Equal(t, "2", resp.Header().Get("X-Total-Count")) + + linkHeader := resp.Header().Get("Link") + assert.NotEmpty(t, linkHeader, "Link header should not be empty") + assert.Contains(t, linkHeader, `rel="next"`) + assert.Contains(t, linkHeader, `rel="last"`) + assert.Contains(t, linkHeader, `/api/v1/repos/user2/repo1/forks?limit=1&page=2>`) + + forks := DecodeJSON(t, resp, []*api.Repository{}) + assert.Len(t, forks, 1) + }) + + t.Run("Page2", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + req := NewRequest(t, "GET", "/api/v1/repos/user2/repo1/forks?page=2&limit=1").AddTokenAuth(user1Token) + resp := MakeRequest(t, req, http.StatusOK) + assert.Equal(t, "2", resp.Header().Get("X-Total-Count")) + + forks := DecodeJSON(t, resp, []*api.Repository{}) + assert.Len(t, forks, 1) + }) + }) } func testGetPrivateReposForks(t *testing.T) {