amplify-excel-migrator 1.1.5__py3-none-any.whl → 1.2.15__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- amplify_excel_migrator/__init__.py +17 -0
- amplify_excel_migrator/auth/__init__.py +6 -0
- amplify_excel_migrator/auth/cognito_auth.py +306 -0
- amplify_excel_migrator/auth/provider.py +42 -0
- amplify_excel_migrator/cli/__init__.py +5 -0
- amplify_excel_migrator/cli/commands.py +165 -0
- amplify_excel_migrator/client.py +47 -0
- amplify_excel_migrator/core/__init__.py +5 -0
- amplify_excel_migrator/core/config.py +98 -0
- amplify_excel_migrator/data/__init__.py +7 -0
- amplify_excel_migrator/data/excel_reader.py +23 -0
- amplify_excel_migrator/data/transformer.py +119 -0
- amplify_excel_migrator/data/validator.py +48 -0
- amplify_excel_migrator/graphql/__init__.py +8 -0
- amplify_excel_migrator/graphql/client.py +137 -0
- amplify_excel_migrator/graphql/executor.py +405 -0
- amplify_excel_migrator/graphql/mutation_builder.py +80 -0
- amplify_excel_migrator/graphql/query_builder.py +194 -0
- amplify_excel_migrator/migration/__init__.py +8 -0
- amplify_excel_migrator/migration/batch_uploader.py +23 -0
- amplify_excel_migrator/migration/failure_tracker.py +92 -0
- amplify_excel_migrator/migration/orchestrator.py +143 -0
- amplify_excel_migrator/migration/progress_reporter.py +57 -0
- amplify_excel_migrator/schema/__init__.py +6 -0
- model_field_parser.py → amplify_excel_migrator/schema/field_parser.py +100 -22
- amplify_excel_migrator/schema/introspector.py +95 -0
- {amplify_excel_migrator-1.1.5.dist-info → amplify_excel_migrator-1.2.15.dist-info}/METADATA +121 -26
- amplify_excel_migrator-1.2.15.dist-info/RECORD +40 -0
- amplify_excel_migrator-1.2.15.dist-info/entry_points.txt +2 -0
- amplify_excel_migrator-1.2.15.dist-info/top_level.txt +2 -0
- tests/__init__.py +1 -0
- tests/test_cli_commands.py +292 -0
- tests/test_client.py +187 -0
- tests/test_cognito_auth.py +363 -0
- tests/test_config_manager.py +347 -0
- tests/test_field_parser.py +615 -0
- tests/test_mutation_builder.py +391 -0
- tests/test_query_builder.py +384 -0
- amplify_client.py +0 -941
- amplify_excel_migrator-1.1.5.dist-info/RECORD +0 -9
- amplify_excel_migrator-1.1.5.dist-info/entry_points.txt +0 -2
- amplify_excel_migrator-1.1.5.dist-info/top_level.txt +0 -3
- migrator.py +0 -437
- {amplify_excel_migrator-1.1.5.dist-info → amplify_excel_migrator-1.2.15.dist-info}/WHEEL +0 -0
- {amplify_excel_migrator-1.1.5.dist-info → amplify_excel_migrator-1.2.15.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,384 @@
|
|
|
1
|
+
"""Tests for QueryBuilder class"""
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
from amplify_excel_migrator.graphql import QueryBuilder
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class TestBuildListQuery:
|
|
8
|
+
"""Test QueryBuilder.build_list_query() method"""
|
|
9
|
+
|
|
10
|
+
def test_basic_list_query_with_pagination(self):
|
|
11
|
+
"""Test basic list query with pagination enabled"""
|
|
12
|
+
query = QueryBuilder.build_list_query("User", fields=["id", "name", "email"])
|
|
13
|
+
|
|
14
|
+
assert "query ListUsers" in query
|
|
15
|
+
assert "$limit: Int" in query
|
|
16
|
+
assert "$nextToken: String" in query
|
|
17
|
+
assert "listUsers(limit: $limit, nextToken: $nextToken)" in query
|
|
18
|
+
assert "items {" in query
|
|
19
|
+
assert "id" in query
|
|
20
|
+
assert "name" in query
|
|
21
|
+
assert "email" in query
|
|
22
|
+
assert "nextToken" in query
|
|
23
|
+
|
|
24
|
+
def test_list_query_without_pagination(self):
|
|
25
|
+
"""Test list query without pagination"""
|
|
26
|
+
query = QueryBuilder.build_list_query("Product", fields=["id", "title"], with_pagination=False)
|
|
27
|
+
|
|
28
|
+
assert "query ListProducts" in query
|
|
29
|
+
assert "$limit: Int" in query
|
|
30
|
+
assert "$nextToken: String" not in query
|
|
31
|
+
assert "listProducts(limit: $limit)" in query
|
|
32
|
+
assert "nextToken" not in query # Should not appear in response
|
|
33
|
+
assert "id" in query
|
|
34
|
+
assert "title" in query
|
|
35
|
+
|
|
36
|
+
def test_list_query_default_fields(self):
|
|
37
|
+
"""Test list query with default fields (only id)"""
|
|
38
|
+
query = QueryBuilder.build_list_query("Post")
|
|
39
|
+
|
|
40
|
+
assert "query ListPosts" in query
|
|
41
|
+
assert "id" in query
|
|
42
|
+
assert "listPosts" in query
|
|
43
|
+
|
|
44
|
+
def test_list_query_multiple_fields(self):
|
|
45
|
+
"""Test list query with multiple fields"""
|
|
46
|
+
fields = ["id", "title", "content", "authorID", "createdAt"]
|
|
47
|
+
query = QueryBuilder.build_list_query("Article", fields=fields)
|
|
48
|
+
|
|
49
|
+
for field in fields:
|
|
50
|
+
assert field in query
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class TestBuildListQueryWithFilter:
|
|
54
|
+
"""Test QueryBuilder.build_list_query_with_filter() method"""
|
|
55
|
+
|
|
56
|
+
def test_filtered_query_with_pagination(self):
|
|
57
|
+
"""Test filtered list query with pagination"""
|
|
58
|
+
query = QueryBuilder.build_list_query_with_filter("User", fields=["id", "name"])
|
|
59
|
+
|
|
60
|
+
assert "query ListUsers" in query
|
|
61
|
+
assert "$filter: ModelUserFilterInput" in query
|
|
62
|
+
assert "$limit: Int" in query
|
|
63
|
+
assert "$nextToken: String" in query
|
|
64
|
+
assert "listUsers(filter: $filter, limit: $limit, nextToken: $nextToken)" in query
|
|
65
|
+
assert "items {" in query
|
|
66
|
+
assert "nextToken" in query
|
|
67
|
+
|
|
68
|
+
def test_filtered_query_without_pagination(self):
|
|
69
|
+
"""Test filtered list query without pagination"""
|
|
70
|
+
query = QueryBuilder.build_list_query_with_filter("Product", fields=["id"], with_pagination=False)
|
|
71
|
+
|
|
72
|
+
assert "query ListProducts" in query
|
|
73
|
+
assert "$filter: ModelProductFilterInput" in query
|
|
74
|
+
assert "$limit: Int" in query
|
|
75
|
+
assert "$nextToken: String" not in query
|
|
76
|
+
assert "listProducts(filter: $filter, limit: $limit)" in query
|
|
77
|
+
assert "nextToken" not in query
|
|
78
|
+
|
|
79
|
+
def test_filtered_query_default_fields(self):
|
|
80
|
+
"""Test filtered query with default fields"""
|
|
81
|
+
query = QueryBuilder.build_list_query_with_filter("Comment")
|
|
82
|
+
|
|
83
|
+
assert "query ListComments" in query
|
|
84
|
+
assert "$filter: ModelCommentFilterInput" in query
|
|
85
|
+
assert "id" in query
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
class TestBuildSecondaryIndexQuery:
|
|
89
|
+
"""Test QueryBuilder.build_secondary_index_query() method"""
|
|
90
|
+
|
|
91
|
+
def test_secondary_index_query_with_pagination(self):
|
|
92
|
+
"""Test secondary index query with pagination"""
|
|
93
|
+
query = QueryBuilder.build_secondary_index_query(
|
|
94
|
+
"User", "email", fields=["id", "email", "name"], field_type="String"
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
assert "query listUserByEmail" in query
|
|
98
|
+
assert "$email: String!" in query
|
|
99
|
+
assert "$limit: Int" in query
|
|
100
|
+
assert "$nextToken: String" in query
|
|
101
|
+
assert "listUserByEmail(email: $email, limit: $limit, nextToken: $nextToken)" in query
|
|
102
|
+
assert "id" in query
|
|
103
|
+
assert "email" in query
|
|
104
|
+
assert "name" in query
|
|
105
|
+
assert "nextToken" in query
|
|
106
|
+
|
|
107
|
+
def test_secondary_index_query_without_pagination(self):
|
|
108
|
+
"""Test secondary index query without pagination"""
|
|
109
|
+
query = QueryBuilder.build_secondary_index_query(
|
|
110
|
+
"Product", "sku", fields=["id", "sku"], field_type="String", with_pagination=False
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
assert "query listProductBySku" in query
|
|
114
|
+
assert "$sku: String!" in query
|
|
115
|
+
assert "$limit: Int" not in query
|
|
116
|
+
assert "$nextToken: String" not in query
|
|
117
|
+
assert "listProductBySku(sku: $sku)" in query
|
|
118
|
+
assert "nextToken" not in query
|
|
119
|
+
|
|
120
|
+
def test_secondary_index_query_different_field_types(self):
|
|
121
|
+
"""Test secondary index query with different field types"""
|
|
122
|
+
# String type
|
|
123
|
+
query_string = QueryBuilder.build_secondary_index_query("Order", "customerId", field_type="String")
|
|
124
|
+
assert "$customerId: String!" in query_string
|
|
125
|
+
|
|
126
|
+
# Int type
|
|
127
|
+
query_int = QueryBuilder.build_secondary_index_query("Order", "orderNumber", field_type="Int")
|
|
128
|
+
assert "$orderNumber: Int!" in query_int
|
|
129
|
+
|
|
130
|
+
# ID type
|
|
131
|
+
query_id = QueryBuilder.build_secondary_index_query("Comment", "postID", field_type="ID")
|
|
132
|
+
assert "$postID: ID!" in query_id
|
|
133
|
+
|
|
134
|
+
def test_secondary_index_query_capitalization(self):
|
|
135
|
+
"""Test that secondary index query name is properly capitalized"""
|
|
136
|
+
query = QueryBuilder.build_secondary_index_query("User", "username", field_type="String")
|
|
137
|
+
|
|
138
|
+
# Should capitalize first letter of field name
|
|
139
|
+
assert "listUserByUsername" in query
|
|
140
|
+
|
|
141
|
+
def test_secondary_index_query_default_fields(self):
|
|
142
|
+
"""Test secondary index query with default fields"""
|
|
143
|
+
query = QueryBuilder.build_secondary_index_query("Product", "category", field_type="String")
|
|
144
|
+
|
|
145
|
+
# Default should include id and the index field
|
|
146
|
+
assert "id" in query
|
|
147
|
+
assert "category" in query
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
class TestBuildGetByIdQuery:
|
|
151
|
+
"""Test QueryBuilder.build_get_by_id_query() method"""
|
|
152
|
+
|
|
153
|
+
def test_get_by_id_basic(self):
|
|
154
|
+
"""Test basic get by ID query"""
|
|
155
|
+
query = QueryBuilder.build_get_by_id_query("User", fields=["id", "name", "email"])
|
|
156
|
+
|
|
157
|
+
assert "query GetUser" in query
|
|
158
|
+
assert "$id: ID!" in query
|
|
159
|
+
assert "getUser(id: $id)" in query
|
|
160
|
+
assert "id" in query
|
|
161
|
+
assert "name" in query
|
|
162
|
+
assert "email" in query
|
|
163
|
+
|
|
164
|
+
def test_get_by_id_default_fields(self):
|
|
165
|
+
"""Test get by ID with default fields (only id)"""
|
|
166
|
+
query = QueryBuilder.build_get_by_id_query("Product")
|
|
167
|
+
|
|
168
|
+
assert "query GetProduct" in query
|
|
169
|
+
assert "$id: ID!" in query
|
|
170
|
+
assert "getProduct(id: $id)" in query
|
|
171
|
+
assert "id" in query
|
|
172
|
+
|
|
173
|
+
def test_get_by_id_single_field(self):
|
|
174
|
+
"""Test get by ID with single field"""
|
|
175
|
+
query = QueryBuilder.build_get_by_id_query("Post", fields=["title"])
|
|
176
|
+
|
|
177
|
+
assert "query GetPost" in query
|
|
178
|
+
assert "title" in query
|
|
179
|
+
|
|
180
|
+
def test_get_by_id_many_fields(self):
|
|
181
|
+
"""Test get by ID with many fields"""
|
|
182
|
+
fields = ["id", "title", "content", "authorID", "createdAt", "updatedAt", "published"]
|
|
183
|
+
query = QueryBuilder.build_get_by_id_query("Article", fields=fields)
|
|
184
|
+
|
|
185
|
+
for field in fields:
|
|
186
|
+
assert field in query
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
class TestBuildIntrospectionQuery:
|
|
190
|
+
"""Test QueryBuilder.build_introspection_query() method"""
|
|
191
|
+
|
|
192
|
+
def test_introspection_query_structure(self):
|
|
193
|
+
"""Test introspection query has correct structure"""
|
|
194
|
+
query = QueryBuilder.build_introspection_query("User")
|
|
195
|
+
|
|
196
|
+
assert "query IntrospectModel" in query
|
|
197
|
+
assert '__type(name: "User")' in query
|
|
198
|
+
assert "name" in query
|
|
199
|
+
assert "fields {" in query
|
|
200
|
+
assert "type {" in query
|
|
201
|
+
assert "kind" in query
|
|
202
|
+
assert "ofType {" in query
|
|
203
|
+
|
|
204
|
+
def test_introspection_query_different_models(self):
|
|
205
|
+
"""Test introspection query with different model names"""
|
|
206
|
+
models = ["User", "Product", "Order", "Comment"]
|
|
207
|
+
|
|
208
|
+
for model in models:
|
|
209
|
+
query = QueryBuilder.build_introspection_query(model)
|
|
210
|
+
assert f'__type(name: "{model}")' in query
|
|
211
|
+
assert "query IntrospectModel" in query
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
class TestBuildVariablesForList:
|
|
215
|
+
"""Test QueryBuilder.build_variables_for_list() method"""
|
|
216
|
+
|
|
217
|
+
def test_variables_with_limit_only(self):
|
|
218
|
+
"""Test variables with only limit"""
|
|
219
|
+
variables = QueryBuilder.build_variables_for_list(limit=100)
|
|
220
|
+
|
|
221
|
+
assert variables == {"limit": 100}
|
|
222
|
+
|
|
223
|
+
def test_variables_with_limit_and_next_token(self):
|
|
224
|
+
"""Test variables with limit and next token"""
|
|
225
|
+
variables = QueryBuilder.build_variables_for_list(limit=50, next_token="abc123")
|
|
226
|
+
|
|
227
|
+
assert variables == {"limit": 50, "nextToken": "abc123"}
|
|
228
|
+
|
|
229
|
+
def test_variables_default_limit(self):
|
|
230
|
+
"""Test variables with default limit"""
|
|
231
|
+
variables = QueryBuilder.build_variables_for_list()
|
|
232
|
+
|
|
233
|
+
assert variables == {"limit": 1000}
|
|
234
|
+
|
|
235
|
+
def test_variables_next_token_none(self):
|
|
236
|
+
"""Test that None next_token is not included"""
|
|
237
|
+
variables = QueryBuilder.build_variables_for_list(limit=100, next_token=None)
|
|
238
|
+
|
|
239
|
+
assert "nextToken" not in variables
|
|
240
|
+
assert variables == {"limit": 100}
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
class TestBuildVariablesForFilter:
|
|
244
|
+
"""Test QueryBuilder.build_variables_for_filter() method"""
|
|
245
|
+
|
|
246
|
+
def test_variables_with_simple_filter(self):
|
|
247
|
+
"""Test variables with simple filter"""
|
|
248
|
+
filter_dict = {"name": {"eq": "John"}}
|
|
249
|
+
variables = QueryBuilder.build_variables_for_filter(filter_dict, limit=100)
|
|
250
|
+
|
|
251
|
+
assert variables == {"filter": {"name": {"eq": "John"}}, "limit": 100}
|
|
252
|
+
|
|
253
|
+
def test_variables_with_filter_and_next_token(self):
|
|
254
|
+
"""Test variables with filter and next token"""
|
|
255
|
+
filter_dict = {"status": {"eq": "active"}}
|
|
256
|
+
variables = QueryBuilder.build_variables_for_filter(filter_dict, limit=50, next_token="xyz789")
|
|
257
|
+
|
|
258
|
+
assert variables == {"filter": {"status": {"eq": "active"}}, "limit": 50, "nextToken": "xyz789"}
|
|
259
|
+
|
|
260
|
+
def test_variables_with_complex_filter(self):
|
|
261
|
+
"""Test variables with complex filter"""
|
|
262
|
+
filter_dict = {"and": [{"age": {"gt": 18}}, {"status": {"eq": "active"}}]}
|
|
263
|
+
variables = QueryBuilder.build_variables_for_filter(filter_dict)
|
|
264
|
+
|
|
265
|
+
assert variables["filter"] == filter_dict
|
|
266
|
+
assert variables["limit"] == 1000
|
|
267
|
+
|
|
268
|
+
def test_variables_filter_none_next_token(self):
|
|
269
|
+
"""Test that None next_token is not included"""
|
|
270
|
+
filter_dict = {"email": {"contains": "@example.com"}}
|
|
271
|
+
variables = QueryBuilder.build_variables_for_filter(filter_dict, next_token=None)
|
|
272
|
+
|
|
273
|
+
assert "nextToken" not in variables
|
|
274
|
+
assert variables == {"filter": filter_dict, "limit": 1000}
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
class TestBuildVariablesForSecondaryIndex:
|
|
278
|
+
"""Test QueryBuilder.build_variables_for_secondary_index() method"""
|
|
279
|
+
|
|
280
|
+
def test_variables_with_index_value(self):
|
|
281
|
+
"""Test variables with index field and value"""
|
|
282
|
+
variables = QueryBuilder.build_variables_for_secondary_index("email", "test@example.com", limit=100)
|
|
283
|
+
|
|
284
|
+
assert variables == {"email": "test@example.com", "limit": 100}
|
|
285
|
+
|
|
286
|
+
def test_variables_with_index_and_next_token(self):
|
|
287
|
+
"""Test variables with index field, value, and next token"""
|
|
288
|
+
variables = QueryBuilder.build_variables_for_secondary_index("sku", "PROD-123", limit=50, next_token="token456")
|
|
289
|
+
|
|
290
|
+
assert variables == {"sku": "PROD-123", "limit": 50, "nextToken": "token456"}
|
|
291
|
+
|
|
292
|
+
def test_variables_default_limit(self):
|
|
293
|
+
"""Test variables with default limit"""
|
|
294
|
+
variables = QueryBuilder.build_variables_for_secondary_index("username", "john_doe")
|
|
295
|
+
|
|
296
|
+
assert variables == {"username": "john_doe", "limit": 1000}
|
|
297
|
+
|
|
298
|
+
def test_variables_different_value_types(self):
|
|
299
|
+
"""Test variables with different value types"""
|
|
300
|
+
# String value
|
|
301
|
+
vars_string = QueryBuilder.build_variables_for_secondary_index("name", "Alice")
|
|
302
|
+
assert vars_string["name"] == "Alice"
|
|
303
|
+
|
|
304
|
+
# Integer value
|
|
305
|
+
vars_int = QueryBuilder.build_variables_for_secondary_index("age", 25)
|
|
306
|
+
assert vars_int["age"] == 25
|
|
307
|
+
|
|
308
|
+
# Boolean value
|
|
309
|
+
vars_bool = QueryBuilder.build_variables_for_secondary_index("isActive", True)
|
|
310
|
+
assert vars_bool["isActive"] is True
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
class TestBuildFilterEquals:
|
|
314
|
+
"""Test QueryBuilder.build_filter_equals() method"""
|
|
315
|
+
|
|
316
|
+
def test_filter_equals_string(self):
|
|
317
|
+
"""Test filter equals with string value"""
|
|
318
|
+
filter_dict = QueryBuilder.build_filter_equals("name", "John")
|
|
319
|
+
|
|
320
|
+
assert filter_dict == {"name": {"eq": "John"}}
|
|
321
|
+
|
|
322
|
+
def test_filter_equals_number(self):
|
|
323
|
+
"""Test filter equals with number value"""
|
|
324
|
+
filter_dict = QueryBuilder.build_filter_equals("age", 30)
|
|
325
|
+
|
|
326
|
+
assert filter_dict == {"age": {"eq": 30}}
|
|
327
|
+
|
|
328
|
+
def test_filter_equals_boolean(self):
|
|
329
|
+
"""Test filter equals with boolean value"""
|
|
330
|
+
filter_dict = QueryBuilder.build_filter_equals("isActive", True)
|
|
331
|
+
|
|
332
|
+
assert filter_dict == {"isActive": {"eq": True}}
|
|
333
|
+
|
|
334
|
+
def test_filter_equals_none(self):
|
|
335
|
+
"""Test filter equals with None value"""
|
|
336
|
+
filter_dict = QueryBuilder.build_filter_equals("deletedAt", None)
|
|
337
|
+
|
|
338
|
+
assert filter_dict == {"deletedAt": {"eq": None}}
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
class TestQueryBuilderIntegration:
|
|
342
|
+
"""Integration tests for QueryBuilder"""
|
|
343
|
+
|
|
344
|
+
def test_list_query_builds_valid_graphql(self):
|
|
345
|
+
"""Test that list query builds syntactically valid GraphQL"""
|
|
346
|
+
query = QueryBuilder.build_list_query("User", fields=["id", "name"])
|
|
347
|
+
|
|
348
|
+
# Should have matching braces
|
|
349
|
+
assert query.count("{") == query.count("}")
|
|
350
|
+
# Should have query keyword
|
|
351
|
+
assert query.startswith("query ")
|
|
352
|
+
|
|
353
|
+
def test_mutation_and_query_are_different(self):
|
|
354
|
+
"""Test that queries don't contain mutation keywords"""
|
|
355
|
+
query = QueryBuilder.build_list_query("User")
|
|
356
|
+
|
|
357
|
+
assert "mutation" not in query.lower()
|
|
358
|
+
assert "query" in query.lower()
|
|
359
|
+
|
|
360
|
+
def test_field_indentation_consistent(self):
|
|
361
|
+
"""Test that fields are properly indented in queries"""
|
|
362
|
+
query = QueryBuilder.build_list_query("User", fields=["id", "name", "email"])
|
|
363
|
+
|
|
364
|
+
# Fields should be indented (have leading spaces)
|
|
365
|
+
lines = query.split("\n")
|
|
366
|
+
field_lines = [line for line in lines if "id" in line or "name" in line or "email" in line]
|
|
367
|
+
|
|
368
|
+
for line in field_lines:
|
|
369
|
+
# Fields inside items should be indented
|
|
370
|
+
if line.strip() in ["id", "name", "email"]:
|
|
371
|
+
assert line.startswith(" ") # 12 spaces for items fields
|
|
372
|
+
|
|
373
|
+
def test_pagination_variables_match_query_signature(self):
|
|
374
|
+
"""Test that pagination variables match the query signature"""
|
|
375
|
+
query_with_pagination = QueryBuilder.build_list_query("User", with_pagination=True)
|
|
376
|
+
query_without_pagination = QueryBuilder.build_list_query("User", with_pagination=False)
|
|
377
|
+
|
|
378
|
+
# With pagination should have both limit and nextToken
|
|
379
|
+
assert "$limit: Int" in query_with_pagination
|
|
380
|
+
assert "$nextToken: String" in query_with_pagination
|
|
381
|
+
|
|
382
|
+
# Without pagination should only have limit
|
|
383
|
+
assert "$limit: Int" in query_without_pagination
|
|
384
|
+
assert "$nextToken: String" not in query_without_pagination
|