2
2
3
3
from typing import Optional
4
4
5
- import pytest
6
5
from pydantic import BaseModel
7
6
8
- from aws_lambda_powertools .event_handler import APIGatewayRestResolver , Response
7
+ from aws_lambda_powertools .event_handler import APIGatewayRestResolver
9
8
from aws_lambda_powertools .event_handler .router import Router
10
9
11
10
@@ -29,24 +28,24 @@ def test_openapi_response_with_headers():
29
28
"examples" : {"example1" : "value1" },
30
29
},
31
30
},
32
- }
31
+ },
33
32
},
34
33
)
35
34
def handler ():
36
35
return {"message" : "hello" }
37
36
38
37
schema = app .get_openapi_schema ()
39
38
response_dict = schema .paths ["/" ].get .responses [200 ]
40
-
39
+
41
40
# Verify headers are present
42
41
assert "headers" in response_dict
43
42
headers = response_dict ["headers" ]
44
-
43
+
45
44
# Check X-Rate-Limit header
46
45
assert "X-Rate-Limit" in headers
47
46
assert headers ["X-Rate-Limit" ]["description" ] == "Rate limit header"
48
47
assert headers ["X-Rate-Limit" ]["schema" ]["type" ] == "integer"
49
-
48
+
50
49
# Check X-Custom-Header with examples
51
50
assert "X-Custom-Header" in headers
52
51
assert headers ["X-Custom-Header" ]["description" ] == "Custom header"
@@ -68,20 +67,20 @@ def test_openapi_response_with_links():
68
67
"operationId" : "getUserOrders" ,
69
68
"parameters" : {"userId" : "$response.body#/id" },
70
69
"description" : "Get orders for this user" ,
71
- }
70
+ },
72
71
},
73
- }
72
+ },
74
73
},
75
74
)
76
75
def get_user (user_id : str ):
77
76
return {"id" : user_id , "name" : "John Doe" }
78
77
79
78
schema = app .get_openapi_schema ()
80
79
response = schema .paths ["/users/{user_id}" ].get .responses [200 ]
81
-
80
+
82
81
# Verify links are present
83
82
links = response .links
84
-
83
+
85
84
assert "GetUserOrders" in links
86
85
assert links ["GetUserOrders" ].operationId == "getUserOrders"
87
86
assert links ["GetUserOrders" ].parameters ["userId" ] == "$response.body#/id"
@@ -115,28 +114,28 @@ class UserResponse(BaseModel):
115
114
"value" : {"id" : 2 , "name" : "Jane" },
116
115
},
117
116
},
118
- }
117
+ },
119
118
},
120
- }
119
+ },
121
120
},
122
121
)
123
122
def handler () -> UserResponse :
124
123
return UserResponse (id = 1 , name = "Test" )
125
124
126
125
schema = app .get_openapi_schema ()
127
126
content = schema .paths ["/" ].get .responses [200 ].content ["application/json" ]
128
-
127
+
129
128
# Verify model schema is present
130
129
assert content .schema_ .ref == "#/components/schemas/UserResponse"
131
-
130
+
132
131
# Verify examples are preserved
133
132
examples = content .examples
134
-
133
+
135
134
assert "example1" in examples
136
135
assert examples ["example1" ].summary == "Example 1"
137
136
assert examples ["example1" ].value ["id" ] == 1
138
137
assert examples ["example1" ].value ["name" ] == "John"
139
-
138
+
140
139
assert "example2" in examples
141
140
assert examples ["example2" ].summary == "Example 2"
142
141
assert examples ["example2" ].value ["id" ] == 2
@@ -166,27 +165,27 @@ class FileUploadResponse(BaseModel):
166
165
"X-Custom-Header" : {
167
166
"description" : "Custom encoding header" ,
168
167
"schema" : {"type" : "string" },
169
- }
168
+ },
170
169
},
171
- }
170
+ },
172
171
},
173
- }
172
+ },
174
173
},
175
- }
174
+ },
176
175
},
177
176
)
178
177
def upload_file () -> FileUploadResponse :
179
178
return FileUploadResponse (file_id = "123" , filename = "test.pdf" , content = b"" )
180
179
181
180
schema = app .get_openapi_schema ()
182
181
content = schema .paths ["/upload" ].post .responses [200 ].content ["multipart/form-data" ]
183
-
182
+
184
183
# Verify model schema is present
185
184
assert content .schema_ .ref == "#/components/schemas/FileUploadResponse"
186
-
185
+
187
186
# Verify encoding is preserved
188
187
encoding = content .encoding
189
-
188
+
190
189
assert "content" in encoding
191
190
assert encoding ["content" ].contentType == "application/octet-stream"
192
191
assert encoding ["content" ].headers is not None
@@ -223,40 +222,40 @@ class DataResponse(BaseModel):
223
222
"success" : {
224
223
"summary" : "Successful response" ,
225
224
"value" : {"data" : "test" , "timestamp" : 1234567890 },
226
- }
225
+ },
227
226
},
228
227
"encoding" : {
229
228
"data" : {
230
229
"contentType" : "text/plain" ,
231
- }
230
+ },
232
231
},
233
- }
232
+ },
234
233
},
235
234
"links" : {
236
235
"next" : {
237
236
"operationId" : "getNextPage" ,
238
237
"parameters" : {"page" : "$response.headers.X-Page + 1" },
239
- }
238
+ },
240
239
},
241
- }
240
+ },
242
241
},
243
242
)
244
243
def get_data () -> DataResponse :
245
244
return DataResponse (data = "test" , timestamp = 1234567890 )
246
245
247
246
schema = app .get_openapi_schema ()
248
247
response = schema .paths ["/data" ].get .responses [200 ]
249
-
248
+
250
249
# Check headers
251
250
assert "X-Total-Count" in response .headers
252
251
assert "X-Page" in response .headers
253
-
252
+
254
253
# Check content with model, examples, and encoding
255
254
content = response .content ["application/json" ]
256
255
assert content .schema_ .ref == "#/components/schemas/DataResponse"
257
256
assert "success" in content .examples
258
257
assert "data" in content .encoding
259
-
258
+
260
259
# Check links
261
260
assert "next" in response .links
262
261
assert response .links ["next" ].operationId == "getNextPage"
@@ -281,7 +280,7 @@ def simple_handler():
281
280
200 : {
282
281
"description" : "With model" ,
283
282
"content" : {"application/json" : {"model" : SimpleResponse }},
284
- }
283
+ },
285
284
},
286
285
)
287
286
def model_handler () -> SimpleResponse :
@@ -294,31 +293,29 @@ def model_handler() -> SimpleResponse:
294
293
200 : {
295
294
"description" : "With schema" ,
296
295
"content" : {
297
- "application/json" : {
298
- "schema" : {"type" : "object" , "properties" : {"msg" : {"type" : "string" }}}
299
- }
296
+ "application/json" : {"schema" : {"type" : "object" , "properties" : {"msg" : {"type" : "string" }}}},
300
297
},
301
- }
298
+ },
302
299
},
303
300
)
304
301
def schema_handler ():
305
302
return {"msg" : "test" }
306
303
307
304
schema = app .get_openapi_schema ()
308
-
305
+
309
306
# Verify all endpoints work
310
307
assert "/simple" in schema .paths
311
308
assert "/with-model" in schema .paths
312
309
assert "/with-schema" in schema .paths
313
-
310
+
314
311
# Check simple response
315
312
simple_response = schema .paths ["/simple" ].get .responses [200 ]
316
313
assert simple_response .description == "Simple response"
317
-
314
+
318
315
# Check model response
319
316
model_response = schema .paths ["/with-model" ].get .responses [200 ]
320
317
assert model_response .content ["application/json" ].schema_ .ref == "#/components/schemas/SimpleResponse"
321
-
318
+
322
319
# Check schema response
323
320
schema_response = schema .paths ["/with-schema" ].get .responses [200 ]
324
321
assert schema_response .content ["application/json" ].schema_ .type == "object"
@@ -340,23 +337,23 @@ def test_openapi_response_empty_optional_fields():
340
337
"schema" : {"type" : "object" },
341
338
"examples" : {}, # Empty examples
342
339
"encoding" : {}, # Empty encoding
343
- }
340
+ },
344
341
},
345
- }
342
+ },
346
343
},
347
344
)
348
345
def empty_handler ():
349
346
return {}
350
347
351
348
schema = app .get_openapi_schema ()
352
349
response = schema .paths ["/empty" ].get .responses [200 ]
353
-
350
+
354
351
# Empty dicts should still be present in the schema
355
352
assert response .headers == {}
356
353
assert response .links == {}
357
-
354
+
358
355
content = response .content ["application/json" ]
359
-
356
+
360
357
# Check if examples and encoding are empty or None (both are valid)
361
358
assert content .examples == {} or content .examples is None
362
359
assert content .encoding == {} or content .encoding is None
@@ -394,25 +391,25 @@ class JsonResponse(BaseModel):
394
391
},
395
392
},
396
393
},
397
- }
394
+ },
398
395
},
399
396
)
400
397
def multi_content_handler ():
401
398
return {"data" : "test" }
402
399
403
400
schema = app .get_openapi_schema ()
404
401
response = schema .paths ["/multi-content" ].get .responses [200 ]
405
-
402
+
406
403
# Check JSON content
407
404
json_content = response .content ["application/json" ]
408
405
assert json_content .schema_ .ref == "#/components/schemas/JsonResponse"
409
406
assert "json_example" in json_content .examples
410
-
407
+
411
408
# Check XML content
412
409
xml_content = response .content ["application/xml" ]
413
410
assert xml_content .schema_ .type == "string"
414
411
assert "xml_example" in xml_content .examples
415
-
412
+
416
413
# Check plain text content
417
414
text_content = response .content ["text/plain" ]
418
415
assert text_content .schema_ .type == "string"
@@ -436,31 +433,31 @@ class RouterResponse(BaseModel):
436
433
"X-Router-Header" : {
437
434
"description" : "Header from router" ,
438
435
"schema" : {"type" : "string" },
439
- }
436
+ },
440
437
},
441
438
"content" : {
442
439
"application/json" : {
443
440
"model" : RouterResponse ,
444
441
"examples" : {
445
442
"router_example" : {"value" : {"result" : "from_router" }},
446
443
},
447
- }
444
+ },
448
445
},
449
- }
446
+ },
450
447
},
451
448
)
452
449
def router_handler () -> RouterResponse :
453
450
return RouterResponse (result = "test" )
454
451
455
452
app .include_router (router )
456
453
schema = app .get_openapi_schema ()
457
-
454
+
458
455
response = schema .paths ["/router-test" ].get .responses [200 ]
459
-
456
+
460
457
# Verify headers
461
458
assert "X-Router-Header" in response .headers
462
-
459
+
463
460
# Verify content with model and examples
464
461
content = response .content ["application/json" ]
465
462
assert content .schema_ .ref == "#/components/schemas/RouterResponse"
466
- assert "router_example" in content .examples
463
+ assert "router_example" in content .examples
0 commit comments