2
2
from unittest import TestCase
3
3
4
4
from fastapi import FastAPI , Request
5
- from piccolo .columns import Integer , Varchar
5
+ from piccolo .columns import ForeignKey , Integer , Varchar
6
6
from piccolo .columns .readable import Readable
7
7
from piccolo .table import Table
8
8
from starlette .responses import JSONResponse
11
11
from piccolo_cursor_pagination .pagination import CursorPagination
12
12
13
13
14
+ class Director (Table ):
15
+ name = Varchar (length = 100 , required = True )
16
+
17
+
14
18
class Movie (Table ):
15
19
name = Varchar (length = 100 , required = True )
16
20
rating = Integer ()
21
+ director = ForeignKey (references = Director )
17
22
18
23
@classmethod
19
24
def get_readable (cls ):
20
- return Readable (template = "%s" , columns = [cls .name ])
25
+ return Readable (template = "%s" , columns = [cls .director . name ])
21
26
22
27
23
28
app = FastAPI ()
@@ -30,22 +35,26 @@ async def movies(
30
35
__previous : t .Optional [str ] = None ,
31
36
):
32
37
try :
33
- cursor = request .query_params ["__cursor" ]
34
- paginator = CursorPagination (cursor = cursor , page_size = 1 , order_by = "id" )
35
- rows_result , headers_result = await paginator .get_cursor_rows (
36
- Movie , request
37
- )
38
- rows = await rows_result .run ()
39
- headers = headers_result
40
- response = JSONResponse (
41
- {"rows" : rows [::- 1 ]},
42
- headers = {
43
- "next_cursor" : headers ["cursor" ],
44
- },
45
- )
38
+ previous = request .query_params ["__previous" ]
39
+ if previous :
40
+ paginator = CursorPagination (
41
+ cursor = __cursor , page_size = 2 , order_by = "id"
42
+ )
43
+ rows_result , headers_result = await paginator .get_cursor_rows (
44
+ Movie , request
45
+ )
46
+ rows = await rows_result .run ()
47
+ headers = headers_result
48
+ response = JSONResponse (
49
+ {"rows" : rows [::- 1 ]},
50
+ headers = {
51
+ "next_cursor" : headers ["cursor" ],
52
+ },
53
+ )
46
54
except KeyError :
47
- cursor = request .query_params ["__cursor" ]
48
- paginator = CursorPagination (cursor = cursor , page_size = 1 , order_by = "id" )
55
+ paginator = CursorPagination (
56
+ cursor = __cursor , page_size = 2 , order_by = "id"
57
+ )
49
58
rows_result , headers_result = await paginator .get_cursor_rows (
50
59
Movie , request
51
60
)
@@ -62,29 +71,67 @@ async def movies(
62
71
63
72
class TestCursorPaginationAsc (TestCase ):
64
73
def setUp (self ):
74
+ Director .create_table (if_not_exists = True ).run_sync ()
65
75
Movie .create_table (if_not_exists = True ).run_sync ()
66
76
67
77
def tearDown (self ):
78
+ Director .alter ().drop_table ().run_sync ()
68
79
Movie .alter ().drop_table ().run_sync ()
69
80
70
81
def test_cursor_pagination_asc (self ):
71
82
"""
72
83
If cursor is applied
73
84
"""
85
+ Director .insert (
86
+ Director (name = "George Lucas" ),
87
+ Director (name = "Ridley Scott" ),
88
+ ).run_sync ()
89
+
74
90
Movie .insert (
75
- Movie (name = "Star Wars" , rating = 93 ),
76
- Movie (name = "Lord of the Rings" , rating = 90 ),
91
+ Movie (name = "Star Wars" , rating = 93 , director = 1 ),
92
+ Movie (name = "Blade Runner" , rating = 90 , director = 2 ),
93
+ Movie (name = "Alien" , rating = 91 , director = 2 ),
77
94
).run_sync ()
78
95
79
96
client = TestClient (app )
80
97
response = client .get ("/movies/" , params = {"__cursor" : "" })
81
98
self .assertTrue (response .status_code , 200 )
82
- self .assertEqual (response .headers ["next_cursor" ], "MQ==" )
99
+ self .assertEqual (response .headers ["next_cursor" ], "Mw==" )
100
+ self .assertEqual (
101
+ response .json (),
102
+ {
103
+ "rows" : [
104
+ {
105
+ "id" : 1 ,
106
+ "name" : "Star Wars" ,
107
+ "rating" : 93 ,
108
+ "director" : 1 ,
109
+ "readable" : "George Lucas" ,
110
+ },
111
+ {
112
+ "id" : 2 ,
113
+ "name" : "Blade Runner" ,
114
+ "rating" : 90 ,
115
+ "director" : 2 ,
116
+ "readable" : "Ridley Scott" ,
117
+ },
118
+ ]
119
+ },
120
+ )
121
+ response = client .get ("/movies/" , params = {"__cursor" : "Mw==" })
122
+ self .assertTrue (response .status_code , 200 )
123
+ self .assertEqual (response .headers ["next_cursor" ], "Mw==" )
83
124
self .assertEqual (
84
125
response .json (),
85
126
{
86
127
"rows" : [
87
- {"id" : 1 , "name" : "Star Wars" , "rating" : 93 },
128
+ {
129
+ "id" : 3 ,
130
+ "name" : "Alien" ,
131
+ "rating" : 91 ,
132
+ "director" : 2 ,
133
+ "readable" : "Ridley Scott" ,
134
+ },
88
135
]
89
136
},
90
137
)
@@ -93,22 +140,41 @@ def test_cursor_pagination_asc_previous(self):
93
140
"""
94
141
If cursor ad previous is applied
95
142
"""
143
+ Director .insert (
144
+ Director (name = "George Lucas" ),
145
+ Director (name = "Ridley Scott" ),
146
+ ).run_sync ()
147
+
96
148
Movie .insert (
97
- Movie (name = "Star Wars" , rating = 93 ),
98
- Movie (name = "Lord of the Rings" , rating = 90 ),
149
+ Movie (name = "Star Wars" , rating = 93 , director = 1 ),
150
+ Movie (name = "Blade Runner" , rating = 90 , director = 2 ),
151
+ Movie (name = "Alien" , rating = 91 , director = 2 ),
99
152
).run_sync ()
100
153
101
154
client = TestClient (app )
102
155
response = client .get (
103
- "/movies/" , params = {"__cursor" : "Mg ==" , "__previous" : "yes" }
156
+ "/movies/" , params = {"__cursor" : "Mw ==" , "__previous" : "yes" }
104
157
)
105
158
self .assertTrue (response .status_code , 200 )
106
159
self .assertEqual (response .headers ["next_cursor" ], "" )
107
160
self .assertEqual (
108
161
response .json (),
109
162
{
110
163
"rows" : [
111
- {"id" : 1 , "name" : "Star Wars" , "rating" : 93 },
164
+ {
165
+ "id" : 1 ,
166
+ "name" : "Star Wars" ,
167
+ "rating" : 93 ,
168
+ "director" : 1 ,
169
+ "readable" : "George Lucas" ,
170
+ },
171
+ {
172
+ "id" : 2 ,
173
+ "name" : "Blade Runner" ,
174
+ "rating" : 90 ,
175
+ "director" : 2 ,
176
+ "readable" : "Ridley Scott" ,
177
+ },
112
178
]
113
179
},
114
180
)
@@ -118,9 +184,15 @@ def test_cursor_pagination_asc_previous_no_more_results(self):
118
184
If cursor is empty and previous is applied there is no
119
185
more results, return empty rows
120
186
"""
187
+ Director .insert (
188
+ Director (name = "George Lucas" ),
189
+ Director (name = "Ridley Scott" ),
190
+ ).run_sync ()
191
+
121
192
Movie .insert (
122
- Movie (name = "Star Wars" , rating = 93 ),
123
- Movie (name = "Lord of the Rings" , rating = 90 ),
193
+ Movie (name = "Star Wars" , rating = 93 , director = 1 ),
194
+ Movie (name = "Blade Runner" , rating = 90 , director = 2 ),
195
+ Movie (name = "Alien" , rating = 91 , director = 2 ),
124
196
).run_sync ()
125
197
126
198
client = TestClient (app )
0 commit comments