Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #1850 from unaizalakain/ticket_13725

Fixed #13725 -- take url scheme into account in assertRedirects

Thanks to Loic for review.
  • Loading branch information...
commit 30203a0deaf82c8af26b1b5453851f83d2248b67 2 parents c29dd76 + 9c5f6cd
@akaariai akaariai authored
View
14 django/test/testcases.py
@@ -246,6 +246,8 @@ def assertRedirects(self, response, expected_url, status_code=302,
if msg_prefix:
msg_prefix += ": "
+ e_scheme, e_netloc, e_path, e_query, e_fragment = urlsplit(expected_url)
+
if hasattr(response, 'redirect_chain'):
# The request was a followed redirect
self.assertTrue(len(response.redirect_chain) > 0,
@@ -259,6 +261,7 @@ def assertRedirects(self, response, expected_url, status_code=302,
(response.redirect_chain[0][1], status_code))
url, status_code = response.redirect_chain[-1]
+ scheme, netloc, path, query, fragment = urlsplit(url)
self.assertEqual(response.status_code, target_status_code,
msg_prefix + "Response didn't redirect as expected: Final"
@@ -276,7 +279,8 @@ def assertRedirects(self, response, expected_url, status_code=302,
scheme, netloc, path, query, fragment = urlsplit(url)
if fetch_redirect_response:
- redirect_response = response.client.get(path, QueryDict(query))
+ redirect_response = response.client.get(path, QueryDict(query),
+ secure=(scheme == 'https'))
# Get the redirection page, using the same client that was used
# to obtain the original response.
@@ -285,10 +289,10 @@ def assertRedirects(self, response, expected_url, status_code=302,
" 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)
- if not (e_scheme or e_netloc):
- expected_url = urlunsplit(('http', host or 'testserver', e_path,
- e_query, e_fragment))
+ e_scheme = e_scheme if e_scheme else scheme or 'http'
+ e_netloc = e_netloc if e_netloc else host or 'testserver'
+ expected_url = urlunsplit((e_scheme, e_netloc, e_path, e_query,
+ e_fragment))
self.assertEqual(url, expected_url,
msg_prefix + "Response redirected to '%s', expected '%s'" %
View
3  docs/releases/1.7.txt
@@ -469,6 +469,9 @@ Tests
client can't fetch externals URLs, this allows you to use ``assertRedirects``
with redirects that aren't part of your Django app.
+* Correct handling of scheme when making comparisons in
+ :meth:`~django.test.SimpleTestCase.assertRedirects`.
+
* The ``secure`` argument was added to all the request methods of
:class:`~django.test.Client`. If ``True``, the request will be made
through HTTPS.
View
7 docs/topics/testing/overview.txt
@@ -1576,6 +1576,13 @@ your test suite.
loaded. Since the test client can't fetch externals URLs, this is
particularly useful if ``expected_url`` isn't part of your Django app.
+ .. versionadded:: 1.7
+
+ Scheme is handled correctly when making comparisons between two URLs. If
+ there isn't any scheme specified in the location where we are redirected to,
+ the original request's scheme is used. If present, the scheme in
+ ``expected_url`` is the one used to make the comparisons to.
+
.. method:: SimpleTestCase.assertHTMLEqual(html1, html2, msg=None)
Asserts that the strings ``html1`` and ``html2`` are equal. The comparison
View
19 tests/test_client_regress/tests.py
@@ -5,6 +5,7 @@
from __future__ import unicode_literals
import os
+import itertools
from django.core.urlresolvers import reverse
from django.template import (TemplateSyntaxError,
@@ -433,6 +434,24 @@ def test_redirect_on_non_redirect_page(self):
except AssertionError as e:
self.assertIn("abc: Response didn't redirect as expected: Response code was 200 (expected 302)", str(e))
+ def test_redirect_scheme(self):
+ "An assertion is raised if the response doesn't have the scheme specified in expected_url"
+
+ # Assure that original request scheme is preserved if no scheme specified in the redirect location
+ response = self.client.get('/test_client/redirect_view/', secure=True)
+ self.assertRedirects(response, 'https://testserver/test_client/get_view/')
+
+ # For all possible True/False combinations of follow and secure
+ for follow, secure in itertools.product([True, False], repeat=2):
+ # always redirects to https
+ response = self.client.get('/test_client/https_redirect_view/', follow=follow, secure=secure)
+ # no scheme to compare too, always succeeds
+ self.assertRedirects(response, '/test_client/secure_view/', status_code=301)
+ # the goal scheme is https
+ self.assertRedirects(response, 'https://testserver/test_client/secure_view/', status_code=301)
+ with self.assertRaises(AssertionError):
+ self.assertRedirects(response, 'http://testserver/test_client/secure_view/', status_code=301)
+
class AssertFormErrorTests(TestCase):
def test_unknown_form(self):
Please sign in to comment.
Something went wrong with that request. Please try again.