File tree Expand file tree Collapse file tree 3 files changed +42
-4
lines changed
tests/unit/common/gunicorn Expand file tree Collapse file tree 3 files changed +42
-4
lines changed Original file line number Diff line number Diff line change 33from django .http import HttpRequest , HttpResponse
44
55from common .gunicorn .constants import WSGI_DJANGO_ROUTE_ENVIRON_KEY
6+ from common .gunicorn .utils import get_route_template
67
78
89class RouteLoggerMiddleware :
@@ -23,6 +24,8 @@ def __call__(self, request: HttpRequest) -> HttpResponse:
2324 if resolver_match := request .resolver_match :
2425 # https://peps.python.org/pep-3333/#specification-details
2526 # "...the application is allowed to modify the dictionary in any way it desires"
26- request .META [WSGI_DJANGO_ROUTE_ENVIRON_KEY ] = resolver_match .route
27+ request .META [WSGI_DJANGO_ROUTE_ENVIRON_KEY ] = get_route_template (
28+ resolver_match .route
29+ )
2730
2831 return response
Original file line number Diff line number Diff line change 11import argparse
22import os
3+ from functools import lru_cache
34from typing import Any
45
56from django .core .handlers .wsgi import WSGIHandler
67from django .core .wsgi import get_wsgi_application
8+ from drf_yasg .generators import EndpointEnumerator # type: ignore[import-untyped]
79from environs import Env
810from gunicorn .app .wsgiapp import ( # type: ignore[import-untyped]
911 WSGIApplication as GunicornWSGIApplication ,
@@ -59,3 +61,18 @@ def add_arguments(parser: argparse.ArgumentParser) -> None:
5961
6062def run_server (options : dict [str , Any ] | None = None ) -> None :
6163 DjangoWSGIApplication (options ).run ()
64+
65+
66+ @lru_cache
67+ def get_route_template (route : str ) -> str :
68+ """
69+ Convert a Django regex route to a template string that can be
70+ searched for in the API documentation.
71+
72+ e.g.,
73+
74+ `"^api/v1/environments/(?P<environment_api_key>[^/.]+)/api-keys/$"` ->
75+ `"/api/v1/environments/{environment_api_key}/api-keys/"`
76+ """
77+ route_template : str = EndpointEnumerator ().get_path_from_regex (route )
78+ return route_template
Original file line number Diff line number Diff line change 44import time
55
66import pytest
7- import pytest_mock
7+ from drf_yasg .generators import EndpointEnumerator # type: ignore[import-untyped]
8+ from pytest_mock import MockerFixture
89
910from common .gunicorn .utils import (
1011 DjangoWSGIApplication ,
12+ get_route_template ,
1113 run_server ,
1214)
1315
1416
1517def test_django_wsgi_application__defaults__expected_config (
16- mocker : pytest_mock . MockerFixture ,
18+ mocker : MockerFixture ,
1719) -> None :
1820 # Given
1921 wsgi_handler_mock = mocker .Mock ()
@@ -37,7 +39,7 @@ def test_django_wsgi_application__defaults__expected_config(
3739
3840def test_run_server__default_config_file__runs_expected (
3941 unused_tcp_port : int ,
40- mocker : pytest_mock . MockerFixture ,
42+ mocker : MockerFixture ,
4143) -> None :
4244 # Given
4345 # prevent real forking from Gunicorn
@@ -58,3 +60,19 @@ def delay_kill(pid: int = pid) -> None:
5860
5961 # Then
6062 mark_process_dead_mock .assert_called_once_with (pid )
63+
64+
65+ def test_get_route_template__returns_expected__caches_expected (
66+ mocker : MockerFixture ,
67+ ) -> None :
68+ # Given
69+ get_path_from_regex_spy = mocker .spy (EndpointEnumerator , "get_path_from_regex" )
70+ regex_route = "^api/v1/environments/(?P<environment_api_key>[^/.]+)/api-keys/$"
71+
72+ # When
73+ result = get_route_template (regex_route )
74+ get_route_template (regex_route )
75+
76+ # Then
77+ assert result == "/api/v1/environments/{environment_api_key}/api-keys/"
78+ get_path_from_regex_spy .assert_called_once ()
You can’t perform that action at this time.
0 commit comments