Kaydet (Commit) a0c2eb46 authored tarafından Claude Paroz's avatar Claude Paroz

Fixed #23960 -- Removed http.fix_location_header

Thanks Carl Meyer for the report and Tim Graham for the review.
üst 0339844b
...@@ -23,7 +23,6 @@ logger = logging.getLogger('django.request') ...@@ -23,7 +23,6 @@ logger = logging.getLogger('django.request')
class BaseHandler(object): class BaseHandler(object):
# Changes that are always applied to a response (in this order). # Changes that are always applied to a response (in this order).
response_fixes = [ response_fixes = [
http.fix_location_header,
http.conditional_content_removal, http.conditional_content_removal,
] ]
......
...@@ -8,7 +8,7 @@ from django.http.response import ( ...@@ -8,7 +8,7 @@ from django.http.response import (
HttpResponseNotFound, HttpResponseNotAllowed, HttpResponseGone, HttpResponseNotFound, HttpResponseNotAllowed, HttpResponseGone,
HttpResponseServerError, Http404, BadHeaderError, JsonResponse, HttpResponseServerError, Http404, BadHeaderError, JsonResponse,
) )
from django.http.utils import fix_location_header, conditional_content_removal from django.http.utils import conditional_content_removal
__all__ = [ __all__ = [
'SimpleCookie', 'parse_cookie', 'HttpRequest', 'QueryDict', 'SimpleCookie', 'parse_cookie', 'HttpRequest', 'QueryDict',
...@@ -17,6 +17,6 @@ __all__ = [ ...@@ -17,6 +17,6 @@ __all__ = [
'HttpResponsePermanentRedirect', 'HttpResponseNotModified', 'HttpResponsePermanentRedirect', 'HttpResponseNotModified',
'HttpResponseBadRequest', 'HttpResponseForbidden', 'HttpResponseNotFound', 'HttpResponseBadRequest', 'HttpResponseForbidden', 'HttpResponseNotFound',
'HttpResponseNotAllowed', 'HttpResponseGone', 'HttpResponseServerError', 'HttpResponseNotAllowed', 'HttpResponseGone', 'HttpResponseServerError',
'Http404', 'BadHeaderError', 'fix_location_header', 'JsonResponse', 'Http404', 'BadHeaderError', 'JsonResponse', 'FileResponse',
'FileResponse', 'conditional_content_removal', 'conditional_content_removal',
] ]
...@@ -9,19 +9,6 @@ Functions that modify an HTTP request or response in some way. ...@@ -9,19 +9,6 @@ Functions that modify an HTTP request or response in some way.
# universally applicable. # universally applicable.
def fix_location_header(request, response):
"""
Ensures that we always use an absolute URI in any location header in the
response. This is required by RFC 2616, section 14.30.
Code constructing response objects is free to insert relative paths, as
this function converts them to absolute paths.
"""
if 'Location' in response:
response['Location'] = request.build_absolute_uri(response['Location'])
return response
def conditional_content_removal(request, response): def conditional_content_removal(request, response):
""" """
Removes the content of responses for HEAD requests, 1xx, 204 and 304 Removes the content of responses for HEAD requests, 1xx, 204 and 304
......
...@@ -86,7 +86,7 @@ class CommonMiddleware(object): ...@@ -86,7 +86,7 @@ class CommonMiddleware(object):
if new_url == old_url: if new_url == old_url:
# No redirects required. # No redirects required.
return return
if new_url[0]: if new_url[0] != old_url[0]:
newurl = "%s://%s%s" % ( newurl = "%s://%s%s" % (
request.scheme, request.scheme,
new_url[0], urlquote(new_url[1])) new_url[0], urlquote(new_url[1]))
......
...@@ -40,16 +40,12 @@ class LocaleMiddleware(object): ...@@ -40,16 +40,12 @@ class LocaleMiddleware(object):
if path_valid: if path_valid:
script_prefix = get_script_prefix() script_prefix = get_script_prefix()
language_url = "%s://%s%s" % ( # Insert language after the script prefix and before the
request.scheme, # rest of the URL
request.get_host(), language_url = request.get_full_path().replace(
# insert language after the script prefix and before the script_prefix,
# rest of the URL '%s%s/' % (script_prefix, language),
request.get_full_path().replace( 1
script_prefix,
'%s%s/' % (script_prefix, language),
1
)
) )
return self.response_redirect_class(language_url) return self.response_redirect_class(language_url)
......
...@@ -37,7 +37,9 @@ from django.test.utils import ( ...@@ -37,7 +37,9 @@ from django.test.utils import (
override_settings, override_settings,
) )
from django.utils import six from django.utils import six
from django.utils.deprecation import RemovedInDjango20Warning from django.utils.deprecation import (
RemovedInDjango20Warning, RemovedInDjango21Warning,
)
from django.utils.encoding import force_text from django.utils.encoding import force_text
from django.utils.six.moves.urllib.parse import ( from django.utils.six.moves.urllib.parse import (
unquote, urlparse, urlsplit, urlunsplit, unquote, urlparse, urlsplit, urlunsplit,
...@@ -249,11 +251,15 @@ class SimpleTestCase(unittest.TestCase): ...@@ -249,11 +251,15 @@ class SimpleTestCase(unittest.TestCase):
TestClient to do a request (use fetch_redirect_response=False to check TestClient to do a request (use fetch_redirect_response=False to check
such links without fetching them). such links without fetching them).
""" """
if host is not None:
warnings.warn(
"The host argument is deprecated and no longer used by assertRedirects",
RemovedInDjango21Warning, stacklevel=2
)
if msg_prefix: if msg_prefix:
msg_prefix += ": " msg_prefix += ": "
e_scheme, e_netloc, e_path, e_query, e_fragment = urlsplit(expected_url)
if hasattr(response, 'redirect_chain'): if hasattr(response, 'redirect_chain'):
# The request was a followed redirect # The request was a followed redirect
self.assertTrue(len(response.redirect_chain) > 0, self.assertTrue(len(response.redirect_chain) > 0,
...@@ -295,10 +301,18 @@ class SimpleTestCase(unittest.TestCase): ...@@ -295,10 +301,18 @@ class SimpleTestCase(unittest.TestCase):
" response code was %d (expected %d)" % " response code was %d (expected %d)" %
(path, redirect_response.status_code, target_status_code)) (path, redirect_response.status_code, target_status_code))
e_scheme = e_scheme if e_scheme else scheme or 'http' if url != expected_url:
e_netloc = e_netloc if e_netloc else host or 'testserver' # For temporary backwards compatibility, try to compare with a relative url
expected_url = urlunsplit((e_scheme, e_netloc, e_path, e_query, e_scheme, e_netloc, e_path, e_query, e_fragment = urlsplit(expected_url)
e_fragment)) relative_url = urlunsplit(('', '', e_path, e_query, e_fragment))
if url == relative_url:
warnings.warn(
"assertRedirects had to strip the scheme and domain from the "
"expected URL, as it was always added automatically to URLs "
"before Django 1.9. Please update your expected URLs by "
"removing the scheme and domain.",
RemovedInDjango21Warning, stacklevel=2)
expected_url = relative_url
self.assertEqual(url, expected_url, self.assertEqual(url, expected_url,
msg_prefix + "Response redirected to '%s', expected '%s'" % msg_prefix + "Response redirected to '%s', expected '%s'" %
......
...@@ -22,6 +22,10 @@ details on these changes. ...@@ -22,6 +22,10 @@ details on these changes.
* The ``assignment_tag`` helper will be removed. * The ``assignment_tag`` helper will be removed.
* The ``host`` argument to ``assertsRedirects`` will be removed. The
compatibility layer which allows absolute URLs to be considered equal to
relative ones when the path is identical will also be removed.
.. _deprecation-removed-in-2.0: .. _deprecation-removed-in-2.0:
2.0 2.0
......
...@@ -824,8 +824,10 @@ types of HTTP responses. Like ``HttpResponse``, these subclasses live in ...@@ -824,8 +824,10 @@ types of HTTP responses. Like ``HttpResponse``, these subclasses live in
The first argument to the constructor is required -- the path to redirect The first argument to the constructor is required -- the path to redirect
to. This can be a fully qualified URL to. This can be a fully qualified URL
(e.g. ``'http://www.yahoo.com/search/'``) or an absolute path with no (e.g. ``'http://www.yahoo.com/search/'``), an absolute path with no domain
domain (e.g. ``'/search/'``). See :class:`HttpResponse` for other optional (e.g. ``'/search/'``), or even a relative path (e.g. ``'search/'``). In that
last case, the client browser will reconstruct the full URL itself
according to the current path. See :class:`HttpResponse` for other optional
constructor arguments. Note that this returns an HTTP status code 302. constructor arguments. Note that this returns an HTTP status code 302.
.. attribute:: HttpResponseRedirect.url .. attribute:: HttpResponseRedirect.url
......
...@@ -266,6 +266,21 @@ a directory. Now, Django only silences the exception if the template source ...@@ -266,6 +266,21 @@ a directory. Now, Django only silences the exception if the template source
does not exist. All other situations result in the original ``IOError`` being does not exist. All other situations result in the original ``IOError`` being
raised. raised.
HTTP redirects no longer forced to absolute URIs
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Relative redirects are no longer converted to absolute URIs. :rfc:`2616`
required the ``Location`` header in redirect responses to be an absolute URI,
but it has been superseded by :rfc:`7231` which allows relative URIs in
``Location``, recognizing the actual practice of user agents, almost all of
which support them.
Consequently, the expected URLs passed to ``assertRedirects`` should generally
no longer include the scheme and domain part of the URLs. For example,
``self.assertRedirects(response, 'http://testserver/some-url/')`` should be
replaced by ``self.assertRedirects(response, '/some-url/')`` (unless the
redirection specifically contained an absolute URL, of course).
Miscellaneous Miscellaneous
~~~~~~~~~~~~~ ~~~~~~~~~~~~~
......
...@@ -1398,7 +1398,7 @@ your test suite. ...@@ -1398,7 +1398,7 @@ your test suite.
You can use this as a context manager in the same way as You can use this as a context manager in the same way as
:meth:`~SimpleTestCase.assertTemplateUsed`. :meth:`~SimpleTestCase.assertTemplateUsed`.
.. method:: SimpleTestCase.assertRedirects(response, expected_url, status_code=302, target_status_code=200, host=None, msg_prefix='', fetch_redirect_response=True) .. method:: SimpleTestCase.assertRedirects(response, expected_url, status_code=302, target_status_code=200, msg_prefix='', fetch_redirect_response=True)
Asserts that the response returned a ``status_code`` redirect status, Asserts that the response returned a ``status_code`` redirect status,
redirected to ``expected_url`` (including any ``GET`` data), and that the redirected to ``expected_url`` (including any ``GET`` data), and that the
...@@ -1408,14 +1408,6 @@ your test suite. ...@@ -1408,14 +1408,6 @@ your test suite.
``target_status_code`` will be the url and status code for the final ``target_status_code`` will be the url and status code for the final
point of the redirect chain. point of the redirect chain.
The ``host`` argument sets a default host if ``expected_url`` doesn't
include one (e.g. ``"/bar/"``). If ``expected_url`` is an absolute URL that
includes a host (e.g. ``"http://testhost/bar/"``), the ``host`` parameter
will be ignored. Note that the test client doesn't support fetching external
URLs, but the parameter may be useful if you are testing with a custom HTTP
host (for example, initializing the test client with
``Client(HTTP_HOST="testhost")``.
If ``fetch_redirect_response`` is ``False``, the final page won't be If ``fetch_redirect_response`` is ``False``, the final page won't be
loaded. Since the test client can't fetch externals URLs, this is loaded. Since the test client can't fetch externals URLs, this is
particularly useful if ``expected_url`` isn't part of your Django app. particularly useful if ``expected_url`` isn't part of your Django app.
...@@ -1425,6 +1417,11 @@ your test suite. ...@@ -1425,6 +1417,11 @@ your test suite.
the original request's scheme is used. If present, the scheme in the original request's scheme is used. If present, the scheme in
``expected_url`` is the one used to make the comparisons to. ``expected_url`` is the one used to make the comparisons to.
.. deprecated:: 1.9
The ``host`` argument is deprecated, as redirections are no longer
forced to be absolute URLs.
.. method:: SimpleTestCase.assertHTMLEqual(html1, html2, msg=None) .. method:: SimpleTestCase.assertHTMLEqual(html1, html2, msg=None)
Asserts that the strings ``html1`` and ``html2`` are equal. The comparison Asserts that the strings ``html1`` and ``html2`` are equal. The comparison
......
...@@ -87,7 +87,7 @@ class BasicFormTests(TestCase): ...@@ -87,7 +87,7 @@ class BasicFormTests(TestCase):
def test_post_data(self): def test_post_data(self):
res = self.client.post('/contact/', {'name': "Me", 'message': "Hello"}) res = self.client.post('/contact/', {'name': "Me", 'message': "Hello"})
self.assertRedirects(res, 'http://testserver/list/authors/') self.assertRedirects(res, '/list/authors/')
class ModelFormMixinTests(TestCase): class ModelFormMixinTests(TestCase):
...@@ -117,7 +117,7 @@ class CreateViewTests(TestCase): ...@@ -117,7 +117,7 @@ class CreateViewTests(TestCase):
res = self.client.post('/edit/authors/create/', res = self.client.post('/edit/authors/create/',
{'name': 'Randall Munroe', 'slug': 'randall-munroe'}) {'name': 'Randall Munroe', 'slug': 'randall-munroe'})
self.assertEqual(res.status_code, 302) self.assertEqual(res.status_code, 302)
self.assertRedirects(res, 'http://testserver/list/authors/') self.assertRedirects(res, '/list/authors/')
self.assertQuerysetEqual(Author.objects.all(), ['<Author: Randall Munroe>']) self.assertQuerysetEqual(Author.objects.all(), ['<Author: Randall Munroe>'])
def test_create_invalid(self): def test_create_invalid(self):
...@@ -133,14 +133,14 @@ class CreateViewTests(TestCase): ...@@ -133,14 +133,14 @@ class CreateViewTests(TestCase):
{'name': 'Rene Magritte'}) {'name': 'Rene Magritte'})
self.assertEqual(res.status_code, 302) self.assertEqual(res.status_code, 302)
artist = Artist.objects.get(name='Rene Magritte') artist = Artist.objects.get(name='Rene Magritte')
self.assertRedirects(res, 'http://testserver/detail/artist/%d/' % artist.pk) self.assertRedirects(res, '/detail/artist/%d/' % artist.pk)
self.assertQuerysetEqual(Artist.objects.all(), ['<Artist: Rene Magritte>']) self.assertQuerysetEqual(Artist.objects.all(), ['<Artist: Rene Magritte>'])
def test_create_with_redirect(self): def test_create_with_redirect(self):
res = self.client.post('/edit/authors/create/redirect/', res = self.client.post('/edit/authors/create/redirect/',
{'name': 'Randall Munroe', 'slug': 'randall-munroe'}) {'name': 'Randall Munroe', 'slug': 'randall-munroe'})
self.assertEqual(res.status_code, 302) self.assertEqual(res.status_code, 302)
self.assertRedirects(res, 'http://testserver/edit/authors/create/') self.assertRedirects(res, '/edit/authors/create/')
self.assertQuerysetEqual(Author.objects.all(), ['<Author: Randall Munroe>']) self.assertQuerysetEqual(Author.objects.all(), ['<Author: Randall Munroe>'])
@ignore_warnings(category=RemovedInDjango20Warning) @ignore_warnings(category=RemovedInDjango20Warning)
...@@ -152,7 +152,7 @@ class CreateViewTests(TestCase): ...@@ -152,7 +152,7 @@ class CreateViewTests(TestCase):
self.assertQuerysetEqual(Author.objects.all(), ['<Author: Randall Munroe>']) self.assertQuerysetEqual(Author.objects.all(), ['<Author: Randall Munroe>'])
self.assertEqual(res.status_code, 302) self.assertEqual(res.status_code, 302)
pk = Author.objects.first().pk pk = Author.objects.first().pk
self.assertRedirects(res, 'http://testserver/edit/author/%d/update/' % pk) self.assertRedirects(res, '/edit/author/%d/update/' % pk)
# Also test with escaped chars in URL # Also test with escaped chars in URL
res = self.client.post( res = self.client.post(
'/edit/authors/create/interpolate_redirect_nonascii/', '/edit/authors/create/interpolate_redirect_nonascii/',
...@@ -160,7 +160,7 @@ class CreateViewTests(TestCase): ...@@ -160,7 +160,7 @@ class CreateViewTests(TestCase):
) )
self.assertEqual(res.status_code, 302) self.assertEqual(res.status_code, 302)
pk = Author.objects.get(name='John Doe').pk pk = Author.objects.get(name='John Doe').pk
self.assertRedirects(res, 'http://testserver/%C3%A9dit/author/{}/update/'.format(pk)) self.assertRedirects(res, '/%C3%A9dit/author/{}/update/'.format(pk))
def test_create_with_special_properties(self): def test_create_with_special_properties(self):
res = self.client.get('/edit/authors/create/special/') res = self.client.get('/edit/authors/create/special/')
...@@ -189,7 +189,7 @@ class CreateViewTests(TestCase): ...@@ -189,7 +189,7 @@ class CreateViewTests(TestCase):
res = self.client.post('/edit/authors/create/restricted/', res = self.client.post('/edit/authors/create/restricted/',
{'name': 'Randall Munroe', 'slug': 'randall-munroe'}) {'name': 'Randall Munroe', 'slug': 'randall-munroe'})
self.assertEqual(res.status_code, 302) self.assertEqual(res.status_code, 302)
self.assertRedirects(res, 'http://testserver/accounts/login/?next=/edit/authors/create/restricted/') self.assertRedirects(res, '/accounts/login/?next=/edit/authors/create/restricted/')
def test_create_view_with_restricted_fields(self): def test_create_view_with_restricted_fields(self):
...@@ -249,7 +249,7 @@ class UpdateViewTests(TestCase): ...@@ -249,7 +249,7 @@ class UpdateViewTests(TestCase):
res = self.client.post('/edit/author/%d/update/' % a.pk, res = self.client.post('/edit/author/%d/update/' % a.pk,
{'name': 'Randall Munroe (xkcd)', 'slug': 'randall-munroe'}) {'name': 'Randall Munroe (xkcd)', 'slug': 'randall-munroe'})
self.assertEqual(res.status_code, 302) self.assertEqual(res.status_code, 302)
self.assertRedirects(res, 'http://testserver/list/authors/') self.assertRedirects(res, '/list/authors/')
self.assertQuerysetEqual(Author.objects.all(), ['<Author: Randall Munroe (xkcd)>']) self.assertQuerysetEqual(Author.objects.all(), ['<Author: Randall Munroe (xkcd)>'])
def test_update_invalid(self): def test_update_invalid(self):
...@@ -269,7 +269,7 @@ class UpdateViewTests(TestCase): ...@@ -269,7 +269,7 @@ class UpdateViewTests(TestCase):
res = self.client.post('/edit/artists/%d/update/' % a.pk, res = self.client.post('/edit/artists/%d/update/' % a.pk,
{'name': 'Rene Magritte'}) {'name': 'Rene Magritte'})
self.assertEqual(res.status_code, 302) self.assertEqual(res.status_code, 302)
self.assertRedirects(res, 'http://testserver/detail/artist/%d/' % a.pk) self.assertRedirects(res, '/detail/artist/%d/' % a.pk)
self.assertQuerysetEqual(Artist.objects.all(), ['<Artist: Rene Magritte>']) self.assertQuerysetEqual(Artist.objects.all(), ['<Artist: Rene Magritte>'])
def test_update_with_redirect(self): def test_update_with_redirect(self):
...@@ -280,7 +280,7 @@ class UpdateViewTests(TestCase): ...@@ -280,7 +280,7 @@ class UpdateViewTests(TestCase):
res = self.client.post('/edit/author/%d/update/redirect/' % a.pk, res = self.client.post('/edit/author/%d/update/redirect/' % a.pk,
{'name': 'Randall Munroe (author of xkcd)', 'slug': 'randall-munroe'}) {'name': 'Randall Munroe (author of xkcd)', 'slug': 'randall-munroe'})
self.assertEqual(res.status_code, 302) self.assertEqual(res.status_code, 302)
self.assertRedirects(res, 'http://testserver/edit/authors/create/') self.assertRedirects(res, '/edit/authors/create/')
self.assertQuerysetEqual(Author.objects.all(), ['<Author: Randall Munroe (author of xkcd)>']) self.assertQuerysetEqual(Author.objects.all(), ['<Author: Randall Munroe (author of xkcd)>'])
@ignore_warnings(category=RemovedInDjango20Warning) @ignore_warnings(category=RemovedInDjango20Warning)
...@@ -296,7 +296,7 @@ class UpdateViewTests(TestCase): ...@@ -296,7 +296,7 @@ class UpdateViewTests(TestCase):
self.assertQuerysetEqual(Author.objects.all(), ['<Author: Randall Munroe (author of xkcd)>']) self.assertQuerysetEqual(Author.objects.all(), ['<Author: Randall Munroe (author of xkcd)>'])
self.assertEqual(res.status_code, 302) self.assertEqual(res.status_code, 302)
pk = Author.objects.first().pk pk = Author.objects.first().pk
self.assertRedirects(res, 'http://testserver/edit/author/%d/update/' % pk) self.assertRedirects(res, '/edit/author/%d/update/' % pk)
# Also test with escaped chars in URL # Also test with escaped chars in URL
res = self.client.post( res = self.client.post(
'/edit/author/%d/update/interpolate_redirect_nonascii/' % a.pk, '/edit/author/%d/update/interpolate_redirect_nonascii/' % a.pk,
...@@ -304,7 +304,7 @@ class UpdateViewTests(TestCase): ...@@ -304,7 +304,7 @@ class UpdateViewTests(TestCase):
) )
self.assertEqual(res.status_code, 302) self.assertEqual(res.status_code, 302)
pk = Author.objects.get(name='John Doe').pk pk = Author.objects.get(name='John Doe').pk
self.assertRedirects(res, 'http://testserver/%C3%A9dit/author/{}/update/'.format(pk)) self.assertRedirects(res, '/%C3%A9dit/author/{}/update/'.format(pk))
def test_update_with_special_properties(self): def test_update_with_special_properties(self):
a = Author.objects.create( a = Author.objects.create(
...@@ -322,7 +322,7 @@ class UpdateViewTests(TestCase): ...@@ -322,7 +322,7 @@ class UpdateViewTests(TestCase):
res = self.client.post('/edit/author/%d/update/special/' % a.pk, res = self.client.post('/edit/author/%d/update/special/' % a.pk,
{'name': 'Randall Munroe (author of xkcd)', 'slug': 'randall-munroe'}) {'name': 'Randall Munroe (author of xkcd)', 'slug': 'randall-munroe'})
self.assertEqual(res.status_code, 302) self.assertEqual(res.status_code, 302)
self.assertRedirects(res, 'http://testserver/detail/author/%d/' % a.pk) self.assertRedirects(res, '/detail/author/%d/' % a.pk)
self.assertQuerysetEqual(Author.objects.all(), ['<Author: Randall Munroe (author of xkcd)>']) self.assertQuerysetEqual(Author.objects.all(), ['<Author: Randall Munroe (author of xkcd)>'])
def test_update_without_redirect(self): def test_update_without_redirect(self):
...@@ -354,7 +354,7 @@ class UpdateViewTests(TestCase): ...@@ -354,7 +354,7 @@ class UpdateViewTests(TestCase):
res = self.client.post('/edit/author/update/', res = self.client.post('/edit/author/update/',
{'name': 'Randall Munroe (xkcd)', 'slug': 'randall-munroe'}) {'name': 'Randall Munroe (xkcd)', 'slug': 'randall-munroe'})
self.assertEqual(res.status_code, 302) self.assertEqual(res.status_code, 302)
self.assertRedirects(res, 'http://testserver/list/authors/') self.assertRedirects(res, '/list/authors/')
self.assertQuerysetEqual(Author.objects.all(), ['<Author: Randall Munroe (xkcd)>']) self.assertQuerysetEqual(Author.objects.all(), ['<Author: Randall Munroe (xkcd)>'])
...@@ -372,7 +372,7 @@ class DeleteViewTests(TestCase): ...@@ -372,7 +372,7 @@ class DeleteViewTests(TestCase):
# Deletion with POST # Deletion with POST
res = self.client.post('/edit/author/%d/delete/' % a.pk) res = self.client.post('/edit/author/%d/delete/' % a.pk)
self.assertEqual(res.status_code, 302) self.assertEqual(res.status_code, 302)
self.assertRedirects(res, 'http://testserver/list/authors/') self.assertRedirects(res, '/list/authors/')
self.assertQuerysetEqual(Author.objects.all(), []) self.assertQuerysetEqual(Author.objects.all(), [])
def test_delete_by_delete(self): def test_delete_by_delete(self):
...@@ -380,14 +380,14 @@ class DeleteViewTests(TestCase): ...@@ -380,14 +380,14 @@ class DeleteViewTests(TestCase):
a = Author.objects.create(**{'name': 'Randall Munroe', 'slug': 'randall-munroe'}) a = Author.objects.create(**{'name': 'Randall Munroe', 'slug': 'randall-munroe'})
res = self.client.delete('/edit/author/%d/delete/' % a.pk) res = self.client.delete('/edit/author/%d/delete/' % a.pk)
self.assertEqual(res.status_code, 302) self.assertEqual(res.status_code, 302)
self.assertRedirects(res, 'http://testserver/list/authors/') self.assertRedirects(res, '/list/authors/')
self.assertQuerysetEqual(Author.objects.all(), []) self.assertQuerysetEqual(Author.objects.all(), [])
def test_delete_with_redirect(self): def test_delete_with_redirect(self):
a = Author.objects.create(**{'name': 'Randall Munroe', 'slug': 'randall-munroe'}) a = Author.objects.create(**{'name': 'Randall Munroe', 'slug': 'randall-munroe'})
res = self.client.post('/edit/author/%d/delete/redirect/' % a.pk) res = self.client.post('/edit/author/%d/delete/redirect/' % a.pk)
self.assertEqual(res.status_code, 302) self.assertEqual(res.status_code, 302)
self.assertRedirects(res, 'http://testserver/edit/authors/create/') self.assertRedirects(res, '/edit/authors/create/')
self.assertQuerysetEqual(Author.objects.all(), []) self.assertQuerysetEqual(Author.objects.all(), [])
@ignore_warnings(category=RemovedInDjango20Warning) @ignore_warnings(category=RemovedInDjango20Warning)
...@@ -395,13 +395,13 @@ class DeleteViewTests(TestCase): ...@@ -395,13 +395,13 @@ class DeleteViewTests(TestCase):
a = Author.objects.create(**{'name': 'Randall Munroe', 'slug': 'randall-munroe'}) a = Author.objects.create(**{'name': 'Randall Munroe', 'slug': 'randall-munroe'})
res = self.client.post('/edit/author/%d/delete/interpolate_redirect/' % a.pk) res = self.client.post('/edit/author/%d/delete/interpolate_redirect/' % a.pk)
self.assertEqual(res.status_code, 302) self.assertEqual(res.status_code, 302)
self.assertRedirects(res, 'http://testserver/edit/authors/create/?deleted=%d' % a.pk) self.assertRedirects(res, '/edit/authors/create/?deleted=%d' % a.pk)
self.assertQuerysetEqual(Author.objects.all(), []) self.assertQuerysetEqual(Author.objects.all(), [])
# Also test with escaped chars in URL # Also test with escaped chars in URL
a = Author.objects.create(**{'name': 'Randall Munroe', 'slug': 'randall-munroe'}) a = Author.objects.create(**{'name': 'Randall Munroe', 'slug': 'randall-munroe'})
res = self.client.post('/edit/author/{}/delete/interpolate_redirect_nonascii/'.format(a.pk)) res = self.client.post('/edit/author/{}/delete/interpolate_redirect_nonascii/'.format(a.pk))
self.assertEqual(res.status_code, 302) self.assertEqual(res.status_code, 302)
self.assertRedirects(res, 'http://testserver/%C3%A9dit/authors/create/?deleted={}'.format(a.pk)) self.assertRedirects(res, '/%C3%A9dit/authors/create/?deleted={}'.format(a.pk))
def test_delete_with_special_properties(self): def test_delete_with_special_properties(self):
a = Author.objects.create(**{'name': 'Randall Munroe', 'slug': 'randall-munroe'}) a = Author.objects.create(**{'name': 'Randall Munroe', 'slug': 'randall-munroe'})
...@@ -414,7 +414,7 @@ class DeleteViewTests(TestCase): ...@@ -414,7 +414,7 @@ class DeleteViewTests(TestCase):
res = self.client.post('/edit/author/%d/delete/special/' % a.pk) res = self.client.post('/edit/author/%d/delete/special/' % a.pk)
self.assertEqual(res.status_code, 302) self.assertEqual(res.status_code, 302)
self.assertRedirects(res, 'http://testserver/list/authors/') self.assertRedirects(res, '/list/authors/')
self.assertQuerysetEqual(Author.objects.all(), []) self.assertQuerysetEqual(Author.objects.all(), [])
def test_delete_without_redirect(self): def test_delete_without_redirect(self):
......
...@@ -3,10 +3,8 @@ from __future__ import unicode_literals ...@@ -3,10 +3,8 @@ from __future__ import unicode_literals
import gzip import gzip
import io import io
from django.http import ( from django.http import HttpRequest, HttpResponse, StreamingHttpResponse
HttpRequest, HttpResponse, HttpResponseRedirect, StreamingHttpResponse, from django.http.utils import conditional_content_removal
)
from django.http.utils import conditional_content_removal, fix_location_header
from django.test import TestCase from django.test import TestCase
...@@ -71,15 +69,3 @@ class HttpUtilTests(TestCase): ...@@ -71,15 +69,3 @@ class HttpUtilTests(TestCase):
res = StreamingHttpResponse(['abc']) res = StreamingHttpResponse(['abc'])
conditional_content_removal(req, res) conditional_content_removal(req, res)
self.assertEqual(b''.join(res), b'') self.assertEqual(b''.join(res), b'')
def test_fix_location_without_get_host(self):
"""
Tests that you can return an absolute redirect when the request
host is not in ALLOWED_HOSTS. Issue #20472
"""
request = HttpRequest()
def bomb():
self.assertTrue(False)
request.get_host = bomb
fix_location_header(request, HttpResponseRedirect('http://example.com'))
...@@ -248,7 +248,7 @@ class URLRedirectWithoutTrailingSlashTests(URLTestCaseBase): ...@@ -248,7 +248,7 @@ class URLRedirectWithoutTrailingSlashTests(URLTestCaseBase):
def test_en_redirect(self): def test_en_redirect(self):
response = self.client.get('/account/register', HTTP_ACCEPT_LANGUAGE='en', follow=True) response = self.client.get('/account/register', HTTP_ACCEPT_LANGUAGE='en', follow=True)
# target status code of 301 because of CommonMiddleware redirecting # target status code of 301 because of CommonMiddleware redirecting
self.assertIn(('http://testserver/en/account/register/', 301), response.redirect_chain) self.assertIn(('/en/account/register/', 301), response.redirect_chain)
self.assertRedirects(response, '/en/account/register/', 302) self.assertRedirects(response, '/en/account/register/', 302)
response = self.client.get('/prefixed.xml', HTTP_ACCEPT_LANGUAGE='en', follow=True) response = self.client.get('/prefixed.xml', HTTP_ACCEPT_LANGUAGE='en', follow=True)
......
...@@ -64,7 +64,7 @@ class CommonMiddlewareTest(TestCase): ...@@ -64,7 +64,7 @@ class CommonMiddlewareTest(TestCase):
request = self.rf.get('/slash') request = self.rf.get('/slash')
r = CommonMiddleware().process_request(request) r = CommonMiddleware().process_request(request)
self.assertEqual(r.status_code, 301) self.assertEqual(r.status_code, 301)
self.assertEqual(r.url, 'http://testserver/slash/') self.assertEqual(r.url, '/slash/')
@override_settings(APPEND_SLASH=True, DEBUG=True) @override_settings(APPEND_SLASH=True, DEBUG=True)
def test_append_slash_no_redirect_on_POST_in_DEBUG(self): def test_append_slash_no_redirect_on_POST_in_DEBUG(self):
...@@ -106,7 +106,7 @@ class CommonMiddlewareTest(TestCase): ...@@ -106,7 +106,7 @@ class CommonMiddlewareTest(TestCase):
self.assertEqual(r.status_code, 301) self.assertEqual(r.status_code, 301)
self.assertEqual( self.assertEqual(
r.url, r.url,
'http://testserver/needsquoting%23/') '/needsquoting%23/')
@override_settings(APPEND_SLASH=False, PREPEND_WWW=True) @override_settings(APPEND_SLASH=False, PREPEND_WWW=True)
def test_prepend_www(self): def test_prepend_www(self):
...@@ -174,7 +174,7 @@ class CommonMiddlewareTest(TestCase): ...@@ -174,7 +174,7 @@ class CommonMiddlewareTest(TestCase):
self.assertIsNotNone(r, self.assertIsNotNone(r,
"CommonMiddlware failed to return APPEND_SLASH redirect using request.urlconf") "CommonMiddlware failed to return APPEND_SLASH redirect using request.urlconf")
self.assertEqual(r.status_code, 301) self.assertEqual(r.status_code, 301)
self.assertEqual(r.url, 'http://testserver/customurlconf/slash/') self.assertEqual(r.url, '/customurlconf/slash/')
@override_settings(APPEND_SLASH=True, DEBUG=True) @override_settings(APPEND_SLASH=True, DEBUG=True)
def test_append_slash_no_redirect_on_POST_in_DEBUG_custom_urlconf(self): def test_append_slash_no_redirect_on_POST_in_DEBUG_custom_urlconf(self):
...@@ -212,7 +212,7 @@ class CommonMiddlewareTest(TestCase): ...@@ -212,7 +212,7 @@ class CommonMiddlewareTest(TestCase):
self.assertEqual(r.status_code, 301) self.assertEqual(r.status_code, 301)
self.assertEqual( self.assertEqual(
r.url, r.url,
'http://testserver/customurlconf/needsquoting%23/') '/customurlconf/needsquoting%23/')
@override_settings(APPEND_SLASH=False, PREPEND_WWW=True) @override_settings(APPEND_SLASH=False, PREPEND_WWW=True)
def test_prepend_www_custom_urlconf(self): def test_prepend_www_custom_urlconf(self):
...@@ -264,7 +264,7 @@ class CommonMiddlewareTest(TestCase): ...@@ -264,7 +264,7 @@ class CommonMiddlewareTest(TestCase):
request = self.rf.get('/slash') request = self.rf.get('/slash')
r = CommonMiddleware().process_request(request) r = CommonMiddleware().process_request(request)
self.assertEqual(r.status_code, 301) self.assertEqual(r.status_code, 301)
self.assertEqual(r.url, 'http://testserver/slash/') self.assertEqual(r.url, '/slash/')
self.assertIsInstance(r, HttpResponsePermanentRedirect) self.assertIsInstance(r, HttpResponsePermanentRedirect)
def test_response_redirect_class_subclass(self): def test_response_redirect_class_subclass(self):
...@@ -274,7 +274,7 @@ class CommonMiddlewareTest(TestCase): ...@@ -274,7 +274,7 @@ class CommonMiddlewareTest(TestCase):
request = self.rf.get('/slash') request = self.rf.get('/slash')
r = MyCommonMiddleware().process_request(request) r = MyCommonMiddleware().process_request(request)
self.assertEqual(r.status_code, 302) self.assertEqual(r.status_code, 302)
self.assertEqual(r.url, 'http://testserver/slash/') self.assertEqual(r.url, '/slash/')
self.assertIsInstance(r, HttpResponseRedirect) self.assertIsInstance(r, HttpResponseRedirect)
......
...@@ -176,40 +176,27 @@ class ClientTest(TestCase): ...@@ -176,40 +176,27 @@ class ClientTest(TestCase):
def test_redirect(self): def test_redirect(self):
"GET a URL that redirects elsewhere" "GET a URL that redirects elsewhere"
response = self.client.get('/redirect_view/') response = self.client.get('/redirect_view/')
# Check that the response was a 302 (redirect) and that # Check that the response was a 302 (redirect)
# assertRedirect() understands to put an implicit http://testserver/ in
# front of non-absolute URLs.
self.assertRedirects(response, '/get_view/') self.assertRedirects(response, '/get_view/')
host = 'django.testserver'
client_providing_host = Client(HTTP_HOST=host)
response = client_providing_host.get('/redirect_view/')
# Check that the response was a 302 (redirect) with absolute URI
self.assertRedirects(response, '/get_view/', host=host)
def test_redirect_with_query(self): def test_redirect_with_query(self):
"GET a URL that redirects with given GET parameters" "GET a URL that redirects with given GET parameters"
response = self.client.get('/redirect_view/', {'var': 'value'}) response = self.client.get('/redirect_view/', {'var': 'value'})
# Check if parameters are intact # Check if parameters are intact
self.assertRedirects(response, 'http://testserver/get_view/?var=value') self.assertRedirects(response, '/get_view/?var=value')
def test_permanent_redirect(self): def test_permanent_redirect(self):
"GET a URL that redirects permanently elsewhere" "GET a URL that redirects permanently elsewhere"
response = self.client.get('/permanent_redirect_view/') response = self.client.get('/permanent_redirect_view/')
# Check that the response was a 301 (permanent redirect) # Check that the response was a 301 (permanent redirect)
self.assertRedirects(response, 'http://testserver/get_view/', status_code=301) self.assertRedirects(response, '/get_view/', status_code=301)
client_providing_host = Client(HTTP_HOST='django.testserver')
response = client_providing_host.get('/permanent_redirect_view/')
# Check that the response was a 301 (permanent redirect) with absolute URI
self.assertRedirects(response, 'http://django.testserver/get_view/', status_code=301)
def test_temporary_redirect(self): def test_temporary_redirect(self):
"GET a URL that does a non-permanent redirect" "GET a URL that does a non-permanent redirect"
response = self.client.get('/temporary_redirect_view/') response = self.client.get('/temporary_redirect_view/')
# Check that the response was a 302 (non-permanent redirect) # Check that the response was a 302 (non-permanent redirect)
self.assertRedirects(response, 'http://testserver/get_view/', status_code=302) self.assertRedirects(response, '/get_view/', status_code=302)
def test_redirect_to_strange_location(self): def test_redirect_to_strange_location(self):
"GET a URL that redirects to a non-200 page" "GET a URL that redirects to a non-200 page"
...@@ -217,12 +204,12 @@ class ClientTest(TestCase): ...@@ -217,12 +204,12 @@ class ClientTest(TestCase):
# Check that the response was a 302, and that # Check that the response was a 302, and that
# the attempt to get the redirection location returned 301 when retrieved # the attempt to get the redirection location returned 301 when retrieved
self.assertRedirects(response, 'http://testserver/permanent_redirect_view/', target_status_code=301) self.assertRedirects(response, '/permanent_redirect_view/', target_status_code=301)
def test_follow_redirect(self): def test_follow_redirect(self):
"A URL that redirects can be followed to termination." "A URL that redirects can be followed to termination."
response = self.client.get('/double_redirect_view/', follow=True) response = self.client.get('/double_redirect_view/', follow=True)
self.assertRedirects(response, 'http://testserver/get_view/', status_code=302, target_status_code=200) self.assertRedirects(response, '/get_view/', status_code=302, target_status_code=200)
self.assertEqual(len(response.redirect_chain), 2) self.assertEqual(len(response.redirect_chain), 2)
def test_redirect_http(self): def test_redirect_http(self):
...@@ -364,7 +351,7 @@ class ClientTest(TestCase): ...@@ -364,7 +351,7 @@ class ClientTest(TestCase):
# Get the page without logging in. Should result in 302. # Get the page without logging in. Should result in 302.
response = self.client.get('/login_protected_view/') response = self.client.get('/login_protected_view/')
self.assertRedirects(response, 'http://testserver/accounts/login/?next=/login_protected_view/') self.assertRedirects(response, '/accounts/login/?next=/login_protected_view/')
# Log in # Log in
login = self.client.login(username='testclient', password='password') login = self.client.login(username='testclient', password='password')
...@@ -380,7 +367,7 @@ class ClientTest(TestCase): ...@@ -380,7 +367,7 @@ class ClientTest(TestCase):
# Get the page without logging in. Should result in 302. # Get the page without logging in. Should result in 302.
response = self.client.get('/login_protected_method_view/') response = self.client.get('/login_protected_method_view/')
self.assertRedirects(response, 'http://testserver/accounts/login/?next=/login_protected_method_view/') self.assertRedirects(response, '/accounts/login/?next=/login_protected_method_view/')
# Log in # Log in
login = self.client.login(username='testclient', password='password') login = self.client.login(username='testclient', password='password')
...@@ -396,7 +383,7 @@ class ClientTest(TestCase): ...@@ -396,7 +383,7 @@ class ClientTest(TestCase):
# Get the page without logging in. Should result in 302. # Get the page without logging in. Should result in 302.
response = self.client.get('/login_protected_view_custom_redirect/') response = self.client.get('/login_protected_view_custom_redirect/')
self.assertRedirects(response, 'http://testserver/accounts/login/?redirect_to=/login_protected_view_custom_redirect/') self.assertRedirects(response, '/accounts/login/?redirect_to=/login_protected_view_custom_redirect/')
# Log in # Log in
login = self.client.login(username='testclient', password='password') login = self.client.login(username='testclient', password='password')
...@@ -434,7 +421,7 @@ class ClientTest(TestCase): ...@@ -434,7 +421,7 @@ class ClientTest(TestCase):
# Request a page that requires a login # Request a page that requires a login
response = self.client.get('/login_protected_view/') response = self.client.get('/login_protected_view/')
self.assertRedirects(response, 'http://testserver/accounts/login/?next=/login_protected_view/') self.assertRedirects(response, '/accounts/login/?next=/login_protected_view/')
@override_settings(SESSION_ENGINE="django.contrib.sessions.backends.signed_cookies") @override_settings(SESSION_ENGINE="django.contrib.sessions.backends.signed_cookies")
def test_logout_cookie_sessions(self): def test_logout_cookie_sessions(self):
...@@ -445,7 +432,7 @@ class ClientTest(TestCase): ...@@ -445,7 +432,7 @@ class ClientTest(TestCase):
# Get the page without logging in. Should result in 302. # Get the page without logging in. Should result in 302.
response = self.client.get('/permission_protected_view/') response = self.client.get('/permission_protected_view/')
self.assertRedirects(response, 'http://testserver/accounts/login/?next=/permission_protected_view/') self.assertRedirects(response, '/accounts/login/?next=/permission_protected_view/')
# Log in # Log in
login = self.client.login(username='testclient', password='password') login = self.client.login(username='testclient', password='password')
...@@ -453,7 +440,7 @@ class ClientTest(TestCase): ...@@ -453,7 +440,7 @@ class ClientTest(TestCase):
# Log in with wrong permissions. Should result in 302. # Log in with wrong permissions. Should result in 302.
response = self.client.get('/permission_protected_view/') response = self.client.get('/permission_protected_view/')
self.assertRedirects(response, 'http://testserver/accounts/login/?next=/permission_protected_view/') self.assertRedirects(response, '/accounts/login/?next=/permission_protected_view/')
# TODO: Log in with right permissions and request the page again # TODO: Log in with right permissions and request the page again
...@@ -477,7 +464,7 @@ class ClientTest(TestCase): ...@@ -477,7 +464,7 @@ class ClientTest(TestCase):
# Get the page without logging in. Should result in 302. # Get the page without logging in. Should result in 302.
response = self.client.get('/permission_protected_method_view/') response = self.client.get('/permission_protected_method_view/')
self.assertRedirects(response, 'http://testserver/accounts/login/?next=/permission_protected_method_view/') self.assertRedirects(response, '/accounts/login/?next=/permission_protected_method_view/')
# Log in # Log in
login = self.client.login(username='testclient', password='password') login = self.client.login(username='testclient', password='password')
...@@ -485,7 +472,7 @@ class ClientTest(TestCase): ...@@ -485,7 +472,7 @@ class ClientTest(TestCase):
# Log in with wrong permissions. Should result in 302. # Log in with wrong permissions. Should result in 302.
response = self.client.get('/permission_protected_method_view/') response = self.client.get('/permission_protected_method_view/')
self.assertRedirects(response, 'http://testserver/accounts/login/?next=/permission_protected_method_view/') self.assertRedirects(response, '/accounts/login/?next=/permission_protected_method_view/')
# TODO: Log in with right permissions and request the page again # TODO: Log in with right permissions and request the page again
......
...@@ -18,7 +18,9 @@ from django.test import Client, TestCase, ignore_warnings, override_settings ...@@ -18,7 +18,9 @@ from django.test import Client, TestCase, ignore_warnings, override_settings
from django.test.client import RedirectCycleError, RequestFactory, encode_file from django.test.client import RedirectCycleError, RequestFactory, encode_file
from django.test.utils import ContextList, str_prefix from django.test.utils import ContextList, str_prefix
from django.utils._os import upath from django.utils._os import upath
from django.utils.deprecation import RemovedInDjango20Warning from django.utils.deprecation import (
RemovedInDjango20Warning, RemovedInDjango21Warning,
)
from django.utils.translation import ugettext_lazy from django.utils.translation import ugettext_lazy
from .models import CustomUser from .models import CustomUser
...@@ -342,12 +344,12 @@ class AssertRedirectsTests(TestCase): ...@@ -342,12 +344,12 @@ class AssertRedirectsTests(TestCase):
try: try:
self.assertRedirects(response, '/get_view/') self.assertRedirects(response, '/get_view/')
except AssertionError as e: except AssertionError as e:
self.assertIn("Response redirected to 'http://testserver/get_view/?var=value', expected 'http://testserver/get_view/'", str(e)) self.assertIn("Response redirected to '/get_view/?var=value', expected '/get_view/'", str(e))
try: try:
self.assertRedirects(response, '/get_view/', msg_prefix='abc') self.assertRedirects(response, '/get_view/', msg_prefix='abc')
except AssertionError as e: except AssertionError as e:
self.assertIn("abc: Response redirected to 'http://testserver/get_view/?var=value', expected 'http://testserver/get_view/'", str(e)) self.assertIn("abc: Response redirected to '/get_view/?var=value', expected '/get_view/'", str(e))
def test_incorrect_target(self): def test_incorrect_target(self):
"An assertion is raised if the response redirects to another target" "An assertion is raised if the response redirects to another target"
...@@ -380,7 +382,7 @@ class AssertRedirectsTests(TestCase): ...@@ -380,7 +382,7 @@ class AssertRedirectsTests(TestCase):
status_code=302, target_status_code=200) status_code=302, target_status_code=200)
self.assertEqual(len(response.redirect_chain), 1) self.assertEqual(len(response.redirect_chain), 1)
self.assertEqual(response.redirect_chain[0], ('http://testserver/no_template_view/', 302)) self.assertEqual(response.redirect_chain[0], ('/no_template_view/', 302))
def test_multiple_redirect_chain(self): def test_multiple_redirect_chain(self):
"You can follow a redirect chain of multiple redirects" "You can follow a redirect chain of multiple redirects"
...@@ -389,9 +391,9 @@ class AssertRedirectsTests(TestCase): ...@@ -389,9 +391,9 @@ class AssertRedirectsTests(TestCase):
status_code=302, target_status_code=200) status_code=302, target_status_code=200)
self.assertEqual(len(response.redirect_chain), 3) self.assertEqual(len(response.redirect_chain), 3)
self.assertEqual(response.redirect_chain[0], ('http://testserver/redirects/further/', 302)) self.assertEqual(response.redirect_chain[0], ('/redirects/further/', 302))
self.assertEqual(response.redirect_chain[1], ('http://testserver/redirects/further/more/', 302)) self.assertEqual(response.redirect_chain[1], ('/redirects/further/more/', 302))
self.assertEqual(response.redirect_chain[2], ('http://testserver/no_template_view/', 302)) self.assertEqual(response.redirect_chain[2], ('/no_template_view/', 302))
def test_redirect_chain_to_non_existent(self): def test_redirect_chain_to_non_existent(self):
"You can follow a chain to a non-existent view" "You can follow a chain to a non-existent view"
...@@ -507,21 +509,24 @@ class AssertRedirectsTests(TestCase): ...@@ -507,21 +509,24 @@ class AssertRedirectsTests(TestCase):
def test_redirect_scheme(self): def test_redirect_scheme(self):
"An assertion is raised if the response doesn't have the scheme specified in expected_url" "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('/redirect_view/', secure=True)
self.assertRedirects(response, 'https://testserver/get_view/')
# For all possible True/False combinations of follow and secure # For all possible True/False combinations of follow and secure
for follow, secure in itertools.product([True, False], repeat=2): for follow, secure in itertools.product([True, False], repeat=2):
# always redirects to https # always redirects to https
response = self.client.get('/https_redirect_view/', follow=follow, secure=secure) response = self.client.get('/https_redirect_view/', follow=follow, secure=secure)
# no scheme to compare too, always succeeds
self.assertRedirects(response, '/secure_view/', status_code=302)
# the goal scheme is https # the goal scheme is https
self.assertRedirects(response, 'https://testserver/secure_view/', status_code=302) self.assertRedirects(response, 'https://testserver/secure_view/', status_code=302)
with self.assertRaises(AssertionError): with self.assertRaises(AssertionError):
self.assertRedirects(response, 'http://testserver/secure_view/', status_code=302) self.assertRedirects(response, 'http://testserver/secure_view/', status_code=302)
@ignore_warnings(category=RemovedInDjango21Warning)
def test_full_path_in_expected_urls(self):
"""
Test that specifying a full URL as assertRedirects expected_url still
work as backwards compatible behavior until Django 2.1.
"""
response = self.client.get('/redirect_view/')
self.assertRedirects(response, 'http://testserver/get_view/')
@override_settings(ROOT_URLCONF='test_client_regress.urls') @override_settings(ROOT_URLCONF='test_client_regress.urls')
class AssertFormErrorTests(TestCase): class AssertFormErrorTests(TestCase):
...@@ -852,7 +857,7 @@ class LoginTests(TestDataMixin, TestCase): ...@@ -852,7 +857,7 @@ class LoginTests(TestDataMixin, TestCase):
# At this points, the self.client isn't logged in. # At this points, the self.client isn't logged in.
# Check that assertRedirects uses the original client, not the # Check that assertRedirects uses the original client, not the
# default client. # default client.
self.assertRedirects(response, "http://testserver/get_view/") self.assertRedirects(response, "/get_view/")
@override_settings( @override_settings(
......
...@@ -32,7 +32,6 @@ urlpatterns = [ ...@@ -32,7 +32,6 @@ urlpatterns = [
url(r'^accounts/logout/$', auth_views.logout), url(r'^accounts/logout/$', auth_views.logout),
# Special URLs for particular regression cases. # Special URLs for particular regression cases.
url('^中文/$', views.redirect),
url('^中文/target/$', views.index_page), url('^中文/target/$', views.index_page),
] ]
......
...@@ -31,7 +31,7 @@ class I18NTests(TestCase): ...@@ -31,7 +31,7 @@ class I18NTests(TestCase):
for lang_code, lang_name in settings.LANGUAGES: for lang_code, lang_name in settings.LANGUAGES:
post_data = dict(language=lang_code, next='/') post_data = dict(language=lang_code, next='/')
response = self.client.post('/i18n/setlang/', data=post_data) response = self.client.post('/i18n/setlang/', data=post_data)
self.assertRedirects(response, 'http://testserver/') self.assertRedirects(response, '/')
self.assertEqual(self.client.session[LANGUAGE_SESSION_KEY], lang_code) self.assertEqual(self.client.session[LANGUAGE_SESSION_KEY], lang_code)
def test_setlang_unsafe_next(self): def test_setlang_unsafe_next(self):
...@@ -42,7 +42,7 @@ class I18NTests(TestCase): ...@@ -42,7 +42,7 @@ class I18NTests(TestCase):
lang_code, lang_name = settings.LANGUAGES[0] lang_code, lang_name = settings.LANGUAGES[0]
post_data = dict(language=lang_code, next='//unsafe/redirection/') post_data = dict(language=lang_code, next='//unsafe/redirection/')
response = self.client.post('/i18n/setlang/', data=post_data) response = self.client.post('/i18n/setlang/', data=post_data)
self.assertEqual(response.url, 'http://testserver/') self.assertEqual(response.url, '/')
self.assertEqual(self.client.session[LANGUAGE_SESSION_KEY], lang_code) self.assertEqual(self.client.session[LANGUAGE_SESSION_KEY], lang_code)
def test_setlang_reversal(self): def test_setlang_reversal(self):
...@@ -76,13 +76,13 @@ class I18NTests(TestCase): ...@@ -76,13 +76,13 @@ class I18NTests(TestCase):
follow=True, HTTP_REFERER='/en/translated/' follow=True, HTTP_REFERER='/en/translated/'
) )
self.assertEqual(self.client.session[LANGUAGE_SESSION_KEY], 'nl') self.assertEqual(self.client.session[LANGUAGE_SESSION_KEY], 'nl')
self.assertRedirects(response, 'http://testserver/nl/vertaald/') self.assertRedirects(response, '/nl/vertaald/')
# And reverse # And reverse
response = self.client.post( response = self.client.post(
'/i18n/setlang/', data={'language': 'en'}, '/i18n/setlang/', data={'language': 'en'},
follow=True, HTTP_REFERER='/nl/vertaald/' follow=True, HTTP_REFERER='/nl/vertaald/'
) )
self.assertRedirects(response, 'http://testserver/en/translated/') self.assertRedirects(response, '/en/translated/')
def test_jsi18n(self): def test_jsi18n(self):
"""The javascript_catalog can be deployed with language settings""" """The javascript_catalog can be deployed with language settings"""
......
...@@ -11,17 +11,6 @@ class URLHandling(TestCase): ...@@ -11,17 +11,6 @@ class URLHandling(TestCase):
""" """
redirect_target = "/%E4%B8%AD%E6%96%87/target/" redirect_target = "/%E4%B8%AD%E6%96%87/target/"
def test_combining_redirect(self):
"""
Tests that redirecting to an IRI, requiring encoding before we use it
in an HTTP response, is handled correctly. In this case the arg to
HttpRedirect is ASCII but the current request path contains non-ASCII
characters so this test ensures the creation of the full path with a
base non-ASCII part is handled correctly.
"""
response = self.client.get('/中文/')
self.assertRedirects(response, self.redirect_target)
def test_nonascii_redirect(self): def test_nonascii_redirect(self):
""" """
Tests that a non-ASCII argument to HttpRedirect is handled properly. Tests that a non-ASCII argument to HttpRedirect is handled properly.
......
...@@ -6,9 +6,7 @@ import sys ...@@ -6,9 +6,7 @@ import sys
from django.core.exceptions import PermissionDenied, SuspiciousOperation from django.core.exceptions import PermissionDenied, SuspiciousOperation
from django.core.urlresolvers import get_resolver from django.core.urlresolvers import get_resolver
from django.http import ( from django.http import Http404, HttpResponse, JsonResponse
Http404, HttpResponse, HttpResponseRedirect, JsonResponse,
)
from django.shortcuts import render, render_to_response from django.shortcuts import render, render_to_response
from django.template import TemplateDoesNotExist from django.template import TemplateDoesNotExist
from django.utils.log import getLogger from django.utils.log import getLogger
...@@ -71,13 +69,6 @@ class Http404View(View): ...@@ -71,13 +69,6 @@ class Http404View(View):
raise Http404("Testing class-based technical 404.") raise Http404("Testing class-based technical 404.")
def redirect(request):
"""
Forces an HTTP redirect.
"""
return HttpResponseRedirect("target/")
def view_exception(request, n): def view_exception(request, n):
raise BrokenException(except_args[int(n)]) raise BrokenException(except_args[int(n)])
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment