Quellcode durchsuchen

Fixed #20919 -- Extended assertRedirects to be able to avoid fetching redirect's response.

Thanks mjtamlyn for the suggestion.
Juan Catalano vor 11 Jahren
Ursprung
Commit
4840fd9cbc

+ 12 - 9
django/test/testcases.py

@@ -225,12 +225,14 @@ class SimpleTestCase(unittest.TestCase):
         return override_settings(**kwargs)
 
     def assertRedirects(self, response, expected_url, status_code=302,
-                        target_status_code=200, host=None, msg_prefix=''):
+                        target_status_code=200, host=None, msg_prefix='',
+                        fetch_redirect_response=True):
         """Asserts that a response redirected to a specific URL, and that the
         redirect URL can be loaded.
 
         Note that assertRedirects won't work for external links since it uses
-        TestClient to do a request.
+        TestClient to do a request (use fetch_redirect_response=False to check
+        such links without fetching thtem).
         """
         if msg_prefix:
             msg_prefix += ": "
@@ -264,14 +266,15 @@ class SimpleTestCase(unittest.TestCase):
             url = response.url
             scheme, netloc, path, query, fragment = urlsplit(url)
 
-            redirect_response = response.client.get(path, QueryDict(query))
+            if fetch_redirect_response:
+                redirect_response = response.client.get(path, QueryDict(query))
 
-            # Get the redirection page, using the same client that was used
-            # to obtain the original response.
-            self.assertEqual(redirect_response.status_code, target_status_code,
-                msg_prefix + "Couldn't retrieve redirection page '%s':"
-                " response code was %d (expected %d)" %
-                    (path, redirect_response.status_code, target_status_code))
+                # Get the redirection page, using the same client that was used
+                # to obtain the original response.
+                self.assertEqual(redirect_response.status_code, target_status_code,
+                    msg_prefix + "Couldn't retrieve redirection page '%s':"
+                    " response code was %d (expected %d)" %
+                        (path, redirect_response.status_code, target_status_code))
 
         e_scheme, e_netloc, e_path, e_query, e_fragment = urlsplit(
                                                               expected_url)

+ 5 - 0
docs/releases/1.7.txt

@@ -293,6 +293,11 @@ Tests
   :attr:`~django.test.runner.DiscoverRunner.test_runner`, which facilitate
   overriding the way tests are collected and run.
 
+* The ``fetch_redirect_response`` argument was added to
+  :meth:`~django.test.SimpleTestCase.assertRedirects`. Since the test
+  client can't fetch externals URLs, this allows you to use ``assertRedirects``
+  with redirects that aren't part of your Django app.
+
 Backwards incompatible changes in 1.7
 =====================================
 

+ 7 - 1
docs/topics/testing/overview.txt

@@ -1542,7 +1542,7 @@ your test suite.
     You can use this as a context manager in the same way as
     :meth:`~SimpleTestCase.assertTemplateUsed`.
 
-.. method:: SimpleTestCase.assertRedirects(response, expected_url, status_code=302, target_status_code=200, msg_prefix='')
+.. method:: SimpleTestCase.assertRedirects(response, expected_url, status_code=302, target_status_code=200, msg_prefix='', fetch_redirect_response=True)
 
     Asserts that the response return a ``status_code`` redirect status, it
     redirected to ``expected_url`` (including any GET data), and the final
@@ -1552,6 +1552,12 @@ your test suite.
     ``target_status_code`` will be the url and status code for the final
     point of the redirect chain.
 
+    .. versionadded:: 1.7
+
+    If ``fetch_redirect_response`` is ``False``, the final page won't be
+    loaded. Since the test client can't fetch externals URLs, this is
+    particularly useful if ``expected_url`` isn't part of your Django app.
+
 .. method:: SimpleTestCase.assertHTMLEqual(html1, html2, msg=None)
 
     Asserts that the strings ``html1`` and ``html2`` are equal. The comparison

+ 4 - 0
tests/test_client/tests.py

@@ -405,6 +405,10 @@ class ClientTest(TestCase):
 
         # TODO: Log in with right permissions and request the page again
 
+    def test_external_redirect(self):
+        response = self.client.get('/test_client/django_project_redirect/')
+        self.assertRedirects(response, 'https://www.djangoproject.com/', fetch_redirect_response=False)
+
     def test_session_modifying_view(self):
         "Request a page that modifies the session"
         # Session value isn't set initially

+ 2 - 1
tests/test_client/urls.py

@@ -29,5 +29,6 @@ urlpatterns = patterns('',
     (r'^session_view/$', views.session_view),
     (r'^broken_view/$', views.broken_view),
     (r'^mail_sending_view/$', views.mail_sending_view),
-    (r'^mass_mail_sending_view/$', views.mass_mail_sending_view)
+    (r'^mass_mail_sending_view/$', views.mass_mail_sending_view),
+    (r'^django_project_redirect/$', views.django_project_redirect),
 )

+ 3 - 0
tests/test_client/views.py

@@ -257,3 +257,6 @@ def mass_mail_sending_view(request):
     c.send_messages([m1,m2])
 
     return HttpResponse("Mail sent")
+
+def django_project_redirect(request):
+    return HttpResponseRedirect('https://www.djangoproject.com/')