Skip to content

Commit

Permalink
Fixed #16087 -- Added ResolverMatch instance to test client response.
Browse files Browse the repository at this point in the history
Thanks mrmachine for the suggestion.
  • Loading branch information
gchp authored and timgraham committed Jun 13, 2014
1 parent 2d42511 commit bf743a4
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 4 deletions.
7 changes: 6 additions & 1 deletion django/test/client.py
Expand Up @@ -10,6 +10,7 @@

from django.apps import apps
from django.conf import settings
from django.core import urlresolvers
from django.core.handlers.base import BaseHandler
from django.core.handlers.wsgi import WSGIRequest
from django.core.signals import (request_started, request_finished,
Expand All @@ -18,7 +19,7 @@
from django.http import SimpleCookie, HttpRequest, QueryDict
from django.template import TemplateDoesNotExist
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.http import urlencode
from django.utils.itercompat import is_iterable
Expand Down Expand Up @@ -449,6 +450,10 @@ def request(self, **request):
response.templates = data.get("templates", [])
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
# the __getattr__ flattening in ContextList, but has some edge-case
# backwards-compatibility implications.
Expand Down
7 changes: 5 additions & 2 deletions docs/releases/1.8.txt
Expand Up @@ -214,8 +214,11 @@ Tests
* The new :meth:`~django.test.SimpleTestCase.assertJSONNotEqual` assertion
allows you to test that two JSON fragments are not equal.

* Added the ability to preserve the test database by adding the :djadminopt:`--keepdb`
flag.
* Added the ability to preserve the test database by adding the
:djadminopt:`--keepdb` flag.

* Added the :attr:`~django.test.Response.resolver_match` attribute to test
client responses.

Validators
^^^^^^^^^^
Expand Down
19 changes: 19 additions & 0 deletions docs/topics/testing/tools.txt
Expand Up @@ -432,6 +432,25 @@ Specifically, a ``Response`` object has the following attributes:
loaded from a file. (The name is a string such as
``'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
of any settings in the HTTP headers. For example, you could determine the
content type of a response using ``response['Content-Type']``.
Expand Down
23 changes: 23 additions & 0 deletions tests/test_client/tests.py
Expand Up @@ -99,6 +99,29 @@ def test_response_attached_request(self):
self.assertIn(key, response.wsgi_request.environ)
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):
"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>"""
Expand Down
2 changes: 1 addition & 1 deletion tests/test_client/urls.py
Expand Up @@ -5,7 +5,7 @@


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'^header_view/$', views.view_with_header),
url(r'^raw_post_view/$', views.raw_post_view),
Expand Down

0 comments on commit bf743a4

Please sign in to comment.