Fixed #16087 -- Added ResolverMatch instance to test client response.

Thanks mrmachine for the suggestion.
This commit is contained in:
Greg Chapple 2014-06-06 15:49:02 +01:00 committed by Tim Graham
parent 2d425116e2
commit bf743a4d57
5 changed files with 54 additions and 4 deletions

View File

@ -10,6 +10,7 @@ from io import BytesIO
from django.apps import apps from django.apps import apps
from django.conf import settings from django.conf import settings
from django.core import urlresolvers
from django.core.handlers.base import BaseHandler from django.core.handlers.base import BaseHandler
from django.core.handlers.wsgi import WSGIRequest from django.core.handlers.wsgi import WSGIRequest
from django.core.signals import (request_started, request_finished, from django.core.signals import (request_started, request_finished,
@ -18,7 +19,7 @@ from django.db import close_old_connections
from django.http import SimpleCookie, HttpRequest, QueryDict from django.http import SimpleCookie, HttpRequest, QueryDict
from django.template import TemplateDoesNotExist from django.template import TemplateDoesNotExist
from django.test import signals from django.test import signals
from django.utils.functional import curry from django.utils.functional import curry, SimpleLazyObject
from django.utils.encoding import force_bytes, force_str from django.utils.encoding import force_bytes, force_str
from django.utils.http import urlencode from django.utils.http import urlencode
from django.utils.itercompat import is_iterable from django.utils.itercompat import is_iterable
@ -449,6 +450,10 @@ class Client(RequestFactory):
response.templates = data.get("templates", []) response.templates = data.get("templates", [])
response.context = data.get("context") response.context = data.get("context")
# Attach the ResolverMatch instance to the response
response.resolver_match = SimpleLazyObject(
lambda: urlresolvers.resolve(request['PATH_INFO']))
# Flatten a single context. Not really necessary anymore thanks to # Flatten a single context. Not really necessary anymore thanks to
# the __getattr__ flattening in ContextList, but has some edge-case # the __getattr__ flattening in ContextList, but has some edge-case
# backwards-compatibility implications. # backwards-compatibility implications.

View File

@ -214,8 +214,11 @@ Tests
* The new :meth:`~django.test.SimpleTestCase.assertJSONNotEqual` assertion * The new :meth:`~django.test.SimpleTestCase.assertJSONNotEqual` assertion
allows you to test that two JSON fragments are not equal. allows you to test that two JSON fragments are not equal.
* Added the ability to preserve the test database by adding the :djadminopt:`--keepdb` * Added the ability to preserve the test database by adding the
flag. :djadminopt:`--keepdb` flag.
* Added the :attr:`~django.test.Response.resolver_match` attribute to test
client responses.
Validators Validators
^^^^^^^^^^ ^^^^^^^^^^

View File

@ -432,6 +432,25 @@ Specifically, a ``Response`` object has the following attributes:
loaded from a file. (The name is a string such as loaded from a file. (The name is a string such as
``'admin/index.html'``.) ``'admin/index.html'``.)
.. attribute:: resolver_match
.. versionadded:: 1.8
An instance of :class:`~django.core.urlresolvers.ResolverMatch` for the
response. You can use the
:attr:`~django.core.urlresolvers.ResolverMatch.func` attribute, for
example, to verify the view that served the response::
# my_view here is a function based view
self.assertEqual(response.resolver_match.func, my_view)
# class based views need to be compared by name, as the functions
# generated by as_view() won't be equal
self.assertEqual(response.resolver_match.func.__name__, MyView.as_view().__name__)
If the given URL is not found, accessing this attribute will raise a
:exc:`~django.core.urlresolvers.Resolver404` exception.
You can also use dictionary syntax on the response object to query the value You can also use dictionary syntax on the response object to query the value
of any settings in the HTTP headers. For example, you could determine the of any settings in the HTTP headers. For example, you could determine the
content type of a response using ``response['Content-Type']``. content type of a response using ``response['Content-Type']``.

View File

@ -99,6 +99,29 @@ class ClientTest(TestCase):
self.assertIn(key, response.wsgi_request.environ) self.assertIn(key, response.wsgi_request.environ)
self.assertEqual(response.wsgi_request.environ[key], value) self.assertEqual(response.wsgi_request.environ[key], value)
def test_response_resolver_match(self):
"""
The response contains a ResolverMatch instance.
"""
response = self.client.get('/header_view/')
self.assertTrue(hasattr(response, 'resolver_match'))
def test_response_resolver_match_redirect_follow(self):
"""
The response ResolverMatch instance contains the correct
information when following redirects.
"""
response = self.client.get('/redirect_view/', follow=True)
self.assertEqual(response.resolver_match.url_name, 'get_view')
def test_response_resolver_match_regular_view(self):
"""
The response ResolverMatch instance contains the correct
information when accessing a regular view.
"""
response = self.client.get('/get_view/')
self.assertEqual(response.resolver_match.url_name, 'get_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"?><library><book><title>Blink</title><author>Malcolm Gladwell</author></book></library>""" test_doc = """<?xml version="1.0" encoding="utf-8"?><library><book><title>Blink</title><author>Malcolm Gladwell</author></book></library>"""

View File

@ -5,7 +5,7 @@ from . import views
urlpatterns = [ urlpatterns = [
url(r'^get_view/$', views.get_view), url(r'^get_view/$', views.get_view, name='get_view'),
url(r'^post_view/$', views.post_view), url(r'^post_view/$', views.post_view),
url(r'^header_view/$', views.view_with_header), url(r'^header_view/$', views.view_with_header),
url(r'^raw_post_view/$', views.raw_post_view), url(r'^raw_post_view/$', views.raw_post_view),