diff --git a/access_application.go b/access_application.go index 2abc6cac5cd..4357fa0d1ef 100644 --- a/access_application.go +++ b/access_application.go @@ -208,7 +208,7 @@ func (api *API) ListAccessApplications(ctx context.Context, rc *ResourceContaine } applications = append(applications, r.Result...) params.ResultInfo = r.ResultInfo.Next() - if params.ResultInfo.Done() || autoPaginate { + if params.ResultInfo.Done() || !autoPaginate { break } } diff --git a/access_ca_certificate.go b/access_ca_certificate.go index 8becc8e7235..8f167875ed5 100644 --- a/access_ca_certificate.go +++ b/access_ca_certificate.go @@ -75,7 +75,7 @@ func (api *API) ListAccessCACertificates(ctx context.Context, rc *ResourceContai } accessCACertificates = append(accessCACertificates, r.Result...) params.ResultInfo = r.ResultInfo.Next() - if params.ResultInfo.Done() || autoPaginate { + if params.ResultInfo.Done() || !autoPaginate { break } } diff --git a/access_group.go b/access_group.go index a21da0df0de..bdb3899adeb 100644 --- a/access_group.go +++ b/access_group.go @@ -286,7 +286,7 @@ func (api *API) ListAccessGroups(ctx context.Context, rc *ResourceContainer, par } accessGroups = append(accessGroups, r.Result...) params.ResultInfo = r.ResultInfo.Next() - if params.ResultInfo.Done() || autoPaginate { + if params.ResultInfo.Done() || !autoPaginate { break } } diff --git a/access_mutual_tls_certificates.go b/access_mutual_tls_certificates.go index a7f29a6a95f..393476c4283 100644 --- a/access_mutual_tls_certificates.go +++ b/access_mutual_tls_certificates.go @@ -98,7 +98,7 @@ func (api *API) ListAccessMutualTLSCertificates(ctx context.Context, rc *Resourc } accessCertificates = append(accessCertificates, r.Result...) params.ResultInfo = r.ResultInfo.Next() - if params.ResultInfo.Done() || autoPaginate { + if params.ResultInfo.Done() || !autoPaginate { break } } diff --git a/access_policy.go b/access_policy.go index b5102e4291c..4219446f24e 100644 --- a/access_policy.go +++ b/access_policy.go @@ -178,7 +178,7 @@ func (api *API) ListAccessPolicies(ctx context.Context, rc *ResourceContainer, p } accessPolicies = append(accessPolicies, r.Result...) params.ResultInfo = r.ResultInfo.Next() - if params.ResultInfo.Done() || autoPaginate { + if params.ResultInfo.Done() || !autoPaginate { break } } diff --git a/pagination.go b/pagination.go index 696dc58ee38..e2ab3735d35 100644 --- a/pagination.go +++ b/pagination.go @@ -1,15 +1,29 @@ package cloudflare +import ( + "math" +) + +// Look first for total_pages, but if total_count and per_page are set then use that to get page count +func (p ResultInfo) getTotalPages() int { + totalPages := p.TotalPages + if totalPages == 0 && p.Total > 0 && p.PerPage > 0 { + totalPages = int(math.Ceil(float64(p.Total) / float64(p.PerPage))) + } + return totalPages +} + // Done returns true for the last page and false otherwise. func (p ResultInfo) Done() bool { // A little hacky but if the response body is lacking a defined `ResultInfo` // object the page will be 1 however the counts will be empty so if we have // that response, we just assume this is the only page. - if p.Page == 1 && p.TotalPages == 0 { + totalPages := p.getTotalPages() + if p.Page == 1 && totalPages == 0 { return true } - return p.Page > 1 && p.Page > p.TotalPages + return p.Page > 1 && p.Page > totalPages } // Next advances the page of a paginated API response, but does not fetch the @@ -18,13 +32,14 @@ func (p ResultInfo) Next() ResultInfo { // A little hacky but if the response body is lacking a defined `ResultInfo` // object the page will be 1 however the counts will be empty so if we have // that response, we just assume this is the only page. - if p.Page == 1 && p.TotalPages == 0 { + totalPages := p.getTotalPages() + if p.Page == 1 && totalPages == 0 { return p } // This shouldn't happen normally however, when it does just return the // current page. - if p.Page > p.TotalPages { + if p.Page > totalPages { return p } @@ -35,9 +50,10 @@ func (p ResultInfo) Next() ResultInfo { // HasMorePages returns whether there is another page of results after the // current one. func (p ResultInfo) HasMorePages() bool { - if p.TotalPages == 0 { + totalPages := p.getTotalPages() + if totalPages == 0 { return false } - return p.Page >= 1 && p.Page < p.TotalPages + return p.Page >= 1 && p.Page < totalPages } diff --git a/pagination_test.go b/pagination_test.go index eb3b07ed227..2a045c63708 100644 --- a/pagination_test.go +++ b/pagination_test.go @@ -28,6 +28,14 @@ func TestPagination_Done(t *testing.T) { r: ResultInfo{Page: 3, TotalPages: 1}, expected: true, }, + "total pages missing but done": { + r: ResultInfo{Page: 4, Total: 70, PerPage: 25}, + expected: true, + }, + "total pages missing and not done": { + r: ResultInfo{Page: 1, Total: 70, PerPage: 25}, + expected: false, + }, } for name, tc := range testCases { @@ -59,6 +67,14 @@ func TestPagination_Next(t *testing.T) { r: ResultInfo{Page: 3, TotalPages: 1}, expected: ResultInfo{Page: 3, TotalPages: 1}, }, + "use per page and greater than page": { + r: ResultInfo{Page: 4, Total: 70, PerPage: 25}, + expected: ResultInfo{Page: 4, Total: 70, PerPage: 25}, + }, + "use per page and less than page": { + r: ResultInfo{Page: 1, Total: 70, PerPage: 25}, + expected: ResultInfo{Page: 2, Total: 70, PerPage: 25}, + }, } for name, tc := range testCases { @@ -93,6 +109,14 @@ func TestPagination_HasMorePages(t *testing.T) { r: ResultInfo{Page: 3, TotalPages: 1}, expected: false, }, + "use per page and greater than page": { + r: ResultInfo{Page: 4, Total: 70, PerPage: 25}, + expected: false, + }, + "use per page and less than page": { + r: ResultInfo{Page: 1, Total: 70, PerPage: 25}, + expected: true, + }, } for name, tc := range testCases {