Skip to content

Commit 1f4c9bb

Browse files
fix: Correctly handle pagination. (#37)
1 parent 76130c4 commit 1f4c9bb

File tree

3 files changed

+102
-4
lines changed

3 files changed

+102
-4
lines changed

data_resource_api/api/v1_0_0/resource_handler.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,17 @@ def build_json_from_object(self, obj: object, restricted_fields: dict = []):
2525
) if not key.startswith('_') and not callable(key) and key not in restricted_fields}
2626
return resp
2727

28-
def compute_offset(self, page, items_per_page):
28+
def compute_offset(self, page: int, items_per_page: int) -> int:
2929
"""Compute the offset value for pagination.
3030
Args:
3131
page (int): The current page to compute the offset from.
3232
items_per_page (int): Number of items per page.
3333
Returns:
3434
int: The offset value.
3535
"""
36-
return (page - 1) * items_per_page
36+
return int(int(int(page) - 1) * int(items_per_page))
3737

38-
def compute_page(self, offset, items_per_page):
38+
def compute_page(self, offset: int, items_per_page: int) -> int:
3939
"""Compute the current page number based on offset.
4040
Args:
4141
offset (int): The offset to use to compute the page.
@@ -44,7 +44,7 @@ def compute_page(self, offset, items_per_page):
4444
int: The page number.
4545
"""
4646

47-
return int(math.ceil((int(offset) / int(items_per_page)))) + 1
47+
return int(math.ceil(((int(offset) + 1) / int(items_per_page))))
4848

4949
def build_links(self, endpoint: str, offset: int, limit: int, rows: int):
5050
"""Build links for a paginated response
@@ -57,6 +57,9 @@ def build_links(self, endpoint: str, offset: int, limit: int, rows: int):
5757
Returns:
5858
dict: The links based on the offset and limit
5959
"""
60+
offset = int(offset)
61+
limit = int(limit)
62+
rows = int(rows)
6063

6164
# URL and pages
6265
url_link = '/{}?offset={}&limit={}'
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
from data_resource_api.api.v1_0_0 import ResourceHandler
2+
from expects import expect, be_an, raise_error, have_property, equal, be_empty, be
3+
import json
4+
5+
6+
class TestComputeOffset(object):
7+
def test_compute_offset(self):
8+
handler = ResourceHandler()
9+
10+
expect(handler.compute_offset(1, 20)).to(equal(0))
11+
# expect(handler.compute_offset(53, 19)).to(equal(0))
12+
# expect(handler.compute_offset(0, 20)).to(equal(0))
13+
14+
# def test_build_links(self):
15+
# handler = ResourceHandler()
16+
17+
# items = [
18+
# handler.build_links('test', 0, 20, 5),
19+
# handler.build_links('test', 1, 20, 55),
20+
# handler.build_links('test', 1, -20, 55)
21+
# ]
22+
23+
# for item in items:
24+
# print(json.dumps(item, indent=4))
25+
26+
def test_compute_page(self):
27+
handler = ResourceHandler()
28+
29+
items = [
30+
handler.compute_page(0, 20),
31+
handler.compute_page(1, 20),
32+
handler.compute_page(20, 20),
33+
handler.compute_page(21, 20),
34+
handler.compute_page(25, 20)
35+
]
36+
37+
for item in items:
38+
print(item)
39+
40+
expect(handler.compute_page(0, 20)).to(equal(1))
41+
expect(handler.compute_page(1, 20)).to(equal(1))
42+
expect(handler.compute_page(19, 20)).to(equal(1))
43+
expect(handler.compute_page(20, 20)).to(equal(2))
44+
expect(handler.compute_page(99, 20)).to(equal(5))

tests/test_default_descriptor.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,3 +89,54 @@ def test_programs(self, regular_client):
8989

9090
expect(response.status_code).to(equal(200))
9191
# expect(body['message']).to(equal('Access Denied'))
92+
93+
def test_pagination(self, regular_client):
94+
def post_a_credential():
95+
post_body = {
96+
"credential_name": "testtesttest"
97+
}
98+
response = regular_client.post('/credentials', json=post_body)
99+
100+
expect(response.status_code).to(equal(201))
101+
102+
body = json.loads(response.data)
103+
return body
104+
105+
body = post_a_credential()
106+
print(json.dumps(body, indent=4))
107+
108+
# do regular get
109+
route = '/credentials'
110+
response = regular_client.get(route)
111+
body = json.loads(response.data)
112+
print(json.dumps(body, indent=4))
113+
114+
expect(response.status_code).to(equal(200))
115+
expect(len(body['credentials'])).not_to(equal(0))
116+
117+
# do get with pagination
118+
route = '/credentials?offset=0&limit=20'
119+
response = regular_client.get(route)
120+
body = json.loads(response.data)
121+
print(json.dumps(body, indent=4))
122+
123+
expect(response.status_code).to(equal(200))
124+
125+
# add items till we need the pagination
126+
for _ in range(100):
127+
body = post_a_credential()
128+
print(json.dumps(body, indent=4))
129+
130+
# do get with pagination
131+
route = '/credentials?offset=0&limit=20'
132+
response = regular_client.get(route)
133+
body = json.loads(response.data)
134+
print(json.dumps(body, indent=4))
135+
expect(len(body['credentials'])).to(equal(20))
136+
137+
# do get with pagination
138+
route = '/credentials?offset=20&limit=20'
139+
response = regular_client.get(route)
140+
body = json.loads(response.data)
141+
print(json.dumps(body, indent=4))
142+
# expect(len(body['credentials'])).to(equal(20))

0 commit comments

Comments
 (0)