Skip to content

Commit 7ca4a3a

Browse files
committed
chore: add middleware order test
Signed-off-by: heitorlessa <lessa@amazon.co.uk>
1 parent b7bcb08 commit 7ca4a3a

File tree

1 file changed

+75
-31
lines changed

1 file changed

+75
-31
lines changed

tests/functional/event_handler/test_api_middlewares.py

Lines changed: 75 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from typing import List
2+
13
import pytest
24

35
from aws_lambda_powertools.event_handler import content_types
@@ -18,6 +20,7 @@
1820
from aws_lambda_powertools.event_handler.middlewares.schema_validation import (
1921
SchemaValidationMiddleware,
2022
)
23+
from aws_lambda_powertools.event_handler.types import EventHandlerInstance
2124
from tests.functional.utils import load_event
2225

2326
API_REST_EVENT = load_event("apiGatewayProxyEvent.json")
@@ -354,54 +357,95 @@ def get_lambda(my_id: str, name: str) -> Response:
354357
(APIGatewayHttpResolver(), API_RESTV2_EVENT),
355358
],
356359
)
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
359362
router = Router()
360363

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")
365367

366-
return response
368+
app.append_context(middleware_order=middleware_order)
369+
return next_middleware(app)
367370

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")
369374

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)
374377

375-
return response
378+
@router.get("/my/path")
379+
def dummy_route():
380+
middleware_order = app.context["middleware_order"]
376381

377-
router.use(middlewares=[router_middleware])
382+
assert middleware_order[0] == "app"
383+
assert middleware_order[1] == "router"
378384

379-
to_inject: str = "injected_value"
385+
return Response(status_code=200, body="works!")
380386

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
385389

386-
return response
390+
router.use([global_router_middleware]) # mimics App importing Router
391+
app.include_router(router)
392+
app.use([global_app_middleware])
387393

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
395399

396-
return Response(200, content_types.TEXT_HTML, injected)
397400

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
398440
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
400446
result = app(event, {})
401447

402-
# THEN process event correctly
403448
assert result["statusCode"] == 200
404-
assert result["body"] == to_inject
405449

406450

407451
def test_class_based_middleware():

0 commit comments

Comments
 (0)