Skip to content

Commit

Permalink
Use path_info when resolving requests
Browse files Browse the repository at this point in the history
Maintains support for `SCRIPT_NAME` without manually calling
`get_script_prefix()`.

Tests that involved manually setting the `path` attribute of a request
have been reworked to use a `RequestFactory` so that the `path` and
`path_info` attributes are both set appropriately.
  • Loading branch information
dmartin authored and matthiask committed Jul 26, 2024
1 parent 23bb473 commit ee258fc
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 40 deletions.
2 changes: 1 addition & 1 deletion debug_toolbar/panels/request.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def generate_stats(self, request, response):
"view_urlname": "None",
}
try:
match = resolve(request.path)
match = resolve(request.path_info)
func, args, kwargs = match
view_info["view_func"] = get_name_from_obj(func)
view_info["view_args"] = args
Expand Down
5 changes: 2 additions & 3 deletions debug_toolbar/toolbar.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from django.dispatch import Signal
from django.template import TemplateSyntaxError
from django.template.loader import render_to_string
from django.urls import get_script_prefix, include, path, re_path, resolve
from django.urls import include, path, re_path, resolve
from django.urls.exceptions import Resolver404
from django.utils.module_loading import import_string
from django.utils.translation import get_language, override as lang_override
Expand Down Expand Up @@ -165,8 +165,7 @@ def is_toolbar_request(cls, request):
# not have resolver_match set.
try:
resolver_match = request.resolver_match or resolve(
request.path.replace(get_script_prefix(), "/", 1),
getattr(request, "urlconf", None),
request.path_info, getattr(request, "urlconf", None)
)
except Resolver404:
return False
Expand Down
21 changes: 12 additions & 9 deletions tests/panels/test_request.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
from django.http import QueryDict
from django.test import RequestFactory

from ..base import BaseTestCase

rf = RequestFactory()


class RequestPanelTestCase(BaseTestCase):
panel_id = "RequestPanel"
Expand All @@ -13,21 +16,21 @@ def test_non_ascii_session(self):
self.assertIn("où", self.panel.content)

def test_object_with_non_ascii_repr_in_request_params(self):
self.request.path = "/non_ascii_request/"
response = self.panel.process_request(self.request)
self.panel.generate_stats(self.request, response)
request = rf.get("/non_ascii_request/")
response = self.panel.process_request(request)
self.panel.generate_stats(request, response)
self.assertIn("nôt åscíì", self.panel.content)

def test_insert_content(self):
"""
Test that the panel only inserts content after generate_stats and
not the process_request.
"""
self.request.path = "/non_ascii_request/"
response = self.panel.process_request(self.request)
request = rf.get("/non_ascii_request/")
response = self.panel.process_request(request)
# ensure the panel does not have content yet.
self.assertNotIn("nôt åscíì", self.panel.content)
self.panel.generate_stats(self.request, response)
self.panel.generate_stats(request, response)
# ensure the panel renders correctly.
content = self.panel.content
self.assertIn("nôt åscíì", content)
Expand Down Expand Up @@ -99,9 +102,9 @@ def test_list_for_request_in_method_post(self):
self.assertIn("[{'a': 1}, {'b': 2}]", content)

def test_namespaced_url(self):
self.request.path = "/admin/login/"
response = self.panel.process_request(self.request)
self.panel.generate_stats(self.request, response)
request = rf.get("/admin/login/")
response = self.panel.process_request(request)
self.panel.generate_stats(request, response)
panel_stats = self.panel.get_stats()
self.assertEqual(panel_stats["view_urlname"], "admin:login")

Expand Down
50 changes: 23 additions & 27 deletions tests/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,10 +128,10 @@ def test_should_render_panels_multiprocess(self):

def _resolve_stats(self, path):
# takes stats from Request panel
self.request.path = path
request = rf.get(path)
panel = self.toolbar.get_panel_by_id("RequestPanel")
response = panel.process_request(self.request)
panel.generate_stats(self.request, response)
response = panel.process_request(request)
panel.generate_stats(request, response)
return panel.get_stats()

def test_url_resolving_positional(self):
Expand Down Expand Up @@ -215,52 +215,48 @@ def test_cache_disable_instrumentation(self):
self.assertEqual(len(response.toolbar.get_panel_by_id("CachePanel").calls), 0)

def test_is_toolbar_request(self):
self.request.path = "/__debug__/render_panel/"
self.assertTrue(self.toolbar.is_toolbar_request(self.request))
request = rf.get("/__debug__/render_panel/")
self.assertTrue(self.toolbar.is_toolbar_request(request))

self.request.path = "/invalid/__debug__/render_panel/"
self.assertFalse(self.toolbar.is_toolbar_request(self.request))
request = rf.get("/invalid/__debug__/render_panel/")
self.assertFalse(self.toolbar.is_toolbar_request(request))

self.request.path = "/render_panel/"
self.assertFalse(self.toolbar.is_toolbar_request(self.request))
request = rf.get("/render_panel/")
self.assertFalse(self.toolbar.is_toolbar_request(request))

@override_settings(ROOT_URLCONF="tests.urls_invalid")
def test_is_toolbar_request_without_djdt_urls(self):
"""Test cases when the toolbar urls aren't configured."""
self.request.path = "/__debug__/render_panel/"
self.assertFalse(self.toolbar.is_toolbar_request(self.request))
request = rf.get("/__debug__/render_panel/")
self.assertFalse(self.toolbar.is_toolbar_request(request))

self.request.path = "/render_panel/"
self.assertFalse(self.toolbar.is_toolbar_request(self.request))
request = rf.get("/render_panel/")
self.assertFalse(self.toolbar.is_toolbar_request(request))

@override_settings(ROOT_URLCONF="tests.urls_invalid")
def test_is_toolbar_request_override_request_urlconf(self):
"""Test cases when the toolbar URL is configured on the request."""
self.request.path = "/__debug__/render_panel/"
self.assertFalse(self.toolbar.is_toolbar_request(self.request))
request = rf.get("/__debug__/render_panel/")
self.assertFalse(self.toolbar.is_toolbar_request(request))

# Verify overriding the urlconf on the request is valid.
self.request.urlconf = "tests.urls"
self.request.path = "/__debug__/render_panel/"
self.assertTrue(self.toolbar.is_toolbar_request(self.request))
request.urlconf = "tests.urls"
self.assertTrue(self.toolbar.is_toolbar_request(request))

@patch("debug_toolbar.toolbar.get_script_prefix", return_value="/path/")
def test_is_toolbar_request_with_script_prefix(self, mocked_get_script_prefix):
def test_is_toolbar_request_with_script_prefix(self):
"""
Test cases when Django is running under a path prefix, such as via the
FORCE_SCRIPT_NAME setting.
"""
self.request.path = "/path/__debug__/render_panel/"
self.assertTrue(self.toolbar.is_toolbar_request(self.request))
request = rf.get("/__debug__/render_panel/", SCRIPT_NAME="/path/")
self.assertTrue(self.toolbar.is_toolbar_request(request))

self.request.path = "/path/invalid/__debug__/render_panel/"
self.assertFalse(self.toolbar.is_toolbar_request(self.request))
request = rf.get("/invalid/__debug__/render_panel/", SCRIPT_NAME="/path/")
self.assertFalse(self.toolbar.is_toolbar_request(request))

self.request.path = "/path/render_panel/"
request = rf.get("/render_panel/", SCRIPT_NAME="/path/")
self.assertFalse(self.toolbar.is_toolbar_request(self.request))

self.assertEqual(mocked_get_script_prefix.call_count, 3)

def test_data_gone(self):
response = self.client.get(
"/__debug__/render_panel/?store_id=GONE&panel_id=RequestPanel"
Expand Down

0 comments on commit ee258fc

Please sign in to comment.