|
| 1 | +from typing import List |
| 2 | + |
1 | 3 | import pytest
|
2 | 4 |
|
3 | 5 | from aws_lambda_powertools.event_handler import content_types
|
|
18 | 20 | from aws_lambda_powertools.event_handler.middlewares.schema_validation import (
|
19 | 21 | SchemaValidationMiddleware,
|
20 | 22 | )
|
| 23 | +from aws_lambda_powertools.event_handler.types import EventHandlerInstance |
21 | 24 | from tests.functional.utils import load_event
|
22 | 25 |
|
23 | 26 | API_REST_EVENT = load_event("apiGatewayProxyEvent.json")
|
@@ -354,54 +357,95 @@ def get_lambda(my_id: str, name: str) -> Response:
|
354 | 357 | (APIGatewayHttpResolver(), API_RESTV2_EVENT),
|
355 | 358 | ],
|
356 | 359 | )
|
357 |
| -def test_api_gateway_app_router_with_middlewares(app: BaseRouter, event): |
358 |
| - # GIVEN a Router with registered routes |
| 360 | +def test_api_gateway_middleware_order_with_include_router_last(app: EventHandlerInstance, event): |
| 361 | + # GIVEN two global middlewares: one for App and one for Router |
359 | 362 | router = Router()
|
360 | 363 |
|
361 |
| - def app_middleware(app: BaseRouter, next_middleware): |
362 |
| - # inject a variable into the resolver context |
363 |
| - app.append_context(app_injected="app_value") |
364 |
| - response = next_middleware(app) |
| 364 | + def global_app_middleware(app: EventHandlerInstance, next_middleware: NextMiddleware): |
| 365 | + middleware_order: List[str] = router.context.get("middleware_order", []) |
| 366 | + middleware_order.append("app") |
365 | 367 |
|
366 |
| - return response |
| 368 | + app.append_context(middleware_order=middleware_order) |
| 369 | + return next_middleware(app) |
367 | 370 |
|
368 |
| - app.use(middlewares=[app_middleware]) |
| 371 | + def global_router_middleware(router: EventHandlerInstance, next_middleware: NextMiddleware): |
| 372 | + middleware_order: List[str] = router.context.get("middleware_order", []) |
| 373 | + middleware_order.append("router") |
369 | 374 |
|
370 |
| - def router_middleware(app: BaseRouter, next_middleware): |
371 |
| - # inject a variable into the resolver context |
372 |
| - app.append_context(router_injected="router_value") |
373 |
| - response = next_middleware(app) |
| 375 | + router.append_context(middleware_order=middleware_order) |
| 376 | + return next_middleware(app) |
374 | 377 |
|
375 |
| - return response |
| 378 | + @router.get("/my/path") |
| 379 | + def dummy_route(): |
| 380 | + middleware_order = app.context["middleware_order"] |
376 | 381 |
|
377 |
| - router.use(middlewares=[router_middleware]) |
| 382 | + assert middleware_order[0] == "app" |
| 383 | + assert middleware_order[1] == "router" |
378 | 384 |
|
379 |
| - to_inject: str = "injected_value" |
| 385 | + return Response(status_code=200, body="works!") |
380 | 386 |
|
381 |
| - def middleware_one(app: BaseRouter, next_middleware: NextMiddleware): |
382 |
| - # inject a variable into the kwargs of the middleware chain |
383 |
| - app.append_context(injected=to_inject) |
384 |
| - response = next_middleware(app) |
| 387 | + # WHEN App global middlewares are registered first |
| 388 | + # followed by include_router |
385 | 389 |
|
386 |
| - return response |
| 390 | + router.use([global_router_middleware]) # mimics App importing Router |
| 391 | + app.include_router(router) |
| 392 | + app.use([global_app_middleware]) |
387 | 393 |
|
388 |
| - @router.get("/my/path", middlewares=[middleware_one]) |
389 |
| - def get_api_route(): |
390 |
| - # make sure value is injected by middleware_one |
391 |
| - injected: str = app.context.get("injected") |
392 |
| - assert injected == to_inject |
393 |
| - assert app.context.get("router_injected") == "router_value" |
394 |
| - assert app.context.get("app_injected") == "app_value" |
| 394 | + # THEN resolving a request should start processing global Router middlewares first |
| 395 | + # due to insertion order |
| 396 | + result = app(event, {}) |
| 397 | + |
| 398 | + assert result["statusCode"] == 200 |
395 | 399 |
|
396 |
| - return Response(200, content_types.TEXT_HTML, injected) |
397 | 400 |
|
| 401 | +@pytest.mark.parametrize( |
| 402 | + "app, event", |
| 403 | + [ |
| 404 | + (ApiGatewayResolver(proxy_type=ProxyEventType.APIGatewayProxyEvent), API_REST_EVENT), |
| 405 | + (APIGatewayRestResolver(), API_REST_EVENT), |
| 406 | + (APIGatewayHttpResolver(), API_RESTV2_EVENT), |
| 407 | + ], |
| 408 | +) |
| 409 | +def test_api_gateway_middleware_order_with_include_router_first(app: EventHandlerInstance, event): |
| 410 | + # GIVEN two global middlewares: one for App and one for Router |
| 411 | + router = Router() |
| 412 | + |
| 413 | + def global_app_middleware(app: EventHandlerInstance, next_middleware: NextMiddleware): |
| 414 | + middleware_order: List[str] = router.context.get("middleware_order", []) |
| 415 | + middleware_order.append("app") |
| 416 | + |
| 417 | + app.append_context(middleware_order=middleware_order) |
| 418 | + return next_middleware(app) |
| 419 | + |
| 420 | + def global_router_middleware(router: EventHandlerInstance, next_middleware: NextMiddleware): |
| 421 | + middleware_order: List[str] = router.context.get("middleware_order", []) |
| 422 | + middleware_order.append("router") |
| 423 | + |
| 424 | + router.append_context(middleware_order=middleware_order) |
| 425 | + return next_middleware(app) |
| 426 | + |
| 427 | + @router.get("/my/path") |
| 428 | + def dummy_route(): |
| 429 | + middleware_order = app.context["middleware_order"] |
| 430 | + |
| 431 | + assert middleware_order[0] == "router" |
| 432 | + assert middleware_order[1] == "app" |
| 433 | + |
| 434 | + return Response(status_code=200, body="works!") |
| 435 | + |
| 436 | + # WHEN App include router middlewares first |
| 437 | + # followed by App global middlewares registration |
| 438 | + |
| 439 | + router.use([global_router_middleware]) # mimics App importing Router |
398 | 440 | app.include_router(router)
|
399 |
| - # WHEN calling the event handler after applying routes from router object |
| 441 | + |
| 442 | + app.use([global_app_middleware]) |
| 443 | + |
| 444 | + # THEN resolving a request should start processing global Router middlewares first |
| 445 | + # due to insertion order |
400 | 446 | result = app(event, {})
|
401 | 447 |
|
402 |
| - # THEN process event correctly |
403 | 448 | assert result["statusCode"] == 200
|
404 |
| - assert result["body"] == to_inject |
405 | 449 |
|
406 | 450 |
|
407 | 451 | def test_class_based_middleware():
|
|
0 commit comments