Fixed #32470 -- Fixed ResolverMatch instance on test clients when request.urlconf is set.

This commit is contained in:
Marc Gibbons 2021-02-21 15:12:41 -05:00 committed by Mariusz Felisiak
parent fb93363c49
commit d6572ee4b0
3 changed files with 50 additions and 3 deletions

View File

@ -725,7 +725,10 @@ class Client(ClientMixin, RequestFactory):
response.context = data.get('context') response.context = data.get('context')
response.json = partial(self._parse_json, response) response.json = partial(self._parse_json, response)
# Attach the ResolverMatch instance to the response. # Attach the ResolverMatch instance to the response.
response.resolver_match = SimpleLazyObject(lambda: resolve(request['PATH_INFO'])) urlconf = getattr(response.wsgi_request, 'urlconf', None)
response.resolver_match = SimpleLazyObject(
lambda: resolve(request['PATH_INFO'], urlconf=urlconf),
)
# Flatten a single context. Not really necessary anymore thanks to the # Flatten a single context. Not really necessary anymore thanks to the
# __getattr__ flattening in ContextList, but has some edge case # __getattr__ flattening in ContextList, but has some edge case
# backwards compatibility implications. # backwards compatibility implications.
@ -914,7 +917,10 @@ class AsyncClient(ClientMixin, AsyncRequestFactory):
response.context = data.get('context') response.context = data.get('context')
response.json = partial(self._parse_json, response) response.json = partial(self._parse_json, response)
# Attach the ResolverMatch instance to the response. # Attach the ResolverMatch instance to the response.
response.resolver_match = SimpleLazyObject(lambda: resolve(request['path'])) urlconf = getattr(response.asgi_request, 'urlconf', None)
response.resolver_match = SimpleLazyObject(
lambda: resolve(request['path'], urlconf=urlconf),
)
# Flatten a single context. Not really necessary anymore thanks to the # Flatten a single context. Not really necessary anymore thanks to the
# __getattr__ flattening in ContextList, but has some edge case # __getattr__ flattening in ContextList, but has some edge case
# backwards compatibility implications. # backwards compatibility implications.

View File

@ -28,13 +28,31 @@ from django.core import mail
from django.http import HttpResponse, HttpResponseNotAllowed from django.http import HttpResponse, HttpResponseNotAllowed
from django.test import ( from django.test import (
AsyncRequestFactory, Client, RequestFactory, SimpleTestCase, TestCase, AsyncRequestFactory, Client, RequestFactory, SimpleTestCase, TestCase,
override_settings, modify_settings, override_settings,
) )
from django.urls import reverse_lazy from django.urls import reverse_lazy
from django.utils.decorators import async_only_middleware
from .views import TwoArgException, get_view, post_view, trace_view from .views import TwoArgException, get_view, post_view, trace_view
def middleware_urlconf(get_response):
def middleware(request):
request.urlconf = 'tests.test_client.urls_middleware_urlconf'
return get_response(request)
return middleware
@async_only_middleware
def async_middleware_urlconf(get_response):
async def middleware(request):
request.urlconf = 'tests.test_client.urls_middleware_urlconf'
return await get_response(request)
return middleware
@override_settings(ROOT_URLCONF='test_client.urls') @override_settings(ROOT_URLCONF='test_client.urls')
class ClientTest(TestCase): class ClientTest(TestCase):
@ -195,6 +213,11 @@ class ClientTest(TestCase):
response = self.client.get('/get_view/') response = self.client.get('/get_view/')
self.assertEqual(response.resolver_match.url_name, 'get_view') self.assertEqual(response.resolver_match.url_name, 'get_view')
@modify_settings(MIDDLEWARE={'prepend': 'test_client.tests.middleware_urlconf'})
def test_response_resolver_match_middleware_urlconf(self):
response = self.client.get('/middleware_urlconf_view/')
self.assertEqual(response.resolver_match.url_name, 'middleware_urlconf_view')
def test_raw_post(self): def test_raw_post(self):
"POST raw data (with a content type) to a view" "POST raw data (with a content type) to a view"
test_doc = """<?xml version="1.0" encoding="utf-8"?> test_doc = """<?xml version="1.0" encoding="utf-8"?>
@ -952,6 +975,13 @@ class AsyncClientTest(TestCase):
self.assertTrue(hasattr(response, 'resolver_match')) self.assertTrue(hasattr(response, 'resolver_match'))
self.assertEqual(response.resolver_match.url_name, 'async_get_view') self.assertEqual(response.resolver_match.url_name, 'async_get_view')
@modify_settings(
MIDDLEWARE={'prepend': 'test_client.tests.async_middleware_urlconf'},
)
async def test_response_resolver_match_middleware_urlconf(self):
response = await self.async_client.get('/middleware_urlconf_view/')
self.assertEqual(response.resolver_match.url_name, 'middleware_urlconf_view')
async def test_follow_parameter_not_implemented(self): async def test_follow_parameter_not_implemented(self):
msg = 'AsyncClient request methods do not accept the follow parameter.' msg = 'AsyncClient request methods do not accept the follow parameter.'
tests = ( tests = (

View File

@ -0,0 +1,11 @@
from django.http import HttpResponse
from django.urls import path
def empty_response(request):
return HttpResponse()
urlpatterns = [
path('middleware_urlconf_view/', empty_response, name='middleware_urlconf_view'),
]