Loading django/test/client.py +6 −1 Original line number Diff line number Diff line Loading @@ -10,6 +10,7 @@ from io import BytesIO 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, Loading @@ -18,7 +19,7 @@ from django.db import close_old_connections 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 Loading Loading @@ -449,6 +450,10 @@ class Client(RequestFactory): 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. Loading docs/releases/1.8.txt +5 −2 Original line number Diff line number Diff line Loading @@ -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 ^^^^^^^^^^ Loading docs/topics/testing/tools.txt +19 −0 Original line number Diff line number Diff line Loading @@ -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']``. Loading tests/test_client/tests.py +23 −0 Original line number Diff line number Diff line Loading @@ -99,6 +99,29 @@ class ClientTest(TestCase): 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>""" Loading tests/test_client/urls.py +1 −1 Original line number Diff line number Diff line Loading @@ -5,7 +5,7 @@ from . import views 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), Loading Loading
django/test/client.py +6 −1 Original line number Diff line number Diff line Loading @@ -10,6 +10,7 @@ from io import BytesIO 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, Loading @@ -18,7 +19,7 @@ from django.db import close_old_connections 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 Loading Loading @@ -449,6 +450,10 @@ class Client(RequestFactory): 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. Loading
docs/releases/1.8.txt +5 −2 Original line number Diff line number Diff line Loading @@ -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 ^^^^^^^^^^ Loading
docs/topics/testing/tools.txt +19 −0 Original line number Diff line number Diff line Loading @@ -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']``. Loading
tests/test_client/tests.py +23 −0 Original line number Diff line number Diff line Loading @@ -99,6 +99,29 @@ class ClientTest(TestCase): 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>""" Loading
tests/test_client/urls.py +1 −1 Original line number Diff line number Diff line Loading @@ -5,7 +5,7 @@ from . import views 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), Loading