Fixed #26428 -- Added support for relative path redirects in assertRedirects().

Thanks Trac alias master for the report and review.
This commit is contained in:
Tim Graham 2016-04-02 10:35:33 -04:00
parent 55c843f2ef
commit d2569f89f2
4 changed files with 19 additions and 2 deletions

View File

@ -41,7 +41,7 @@ from django.utils.decorators import classproperty
from django.utils.deprecation import RemovedInDjango20Warning from django.utils.deprecation import RemovedInDjango20Warning
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, urljoin, urlparse, urlsplit, urlunsplit,
) )
from django.utils.six.moves.urllib.request import url2pathname from django.utils.six.moves.urllib.request import url2pathname
from django.views.static import serve from django.views.static import serve
@ -291,6 +291,11 @@ class SimpleTestCase(unittest.TestCase):
url = response.url url = response.url
scheme, netloc, path, query, fragment = urlsplit(url) scheme, netloc, path, query, fragment = urlsplit(url)
# Prepend the request path to handle relative path redirects.
if not path.startswith('/'):
url = urljoin(response.request['PATH_INFO'], url)
path = urljoin(response.request['PATH_INFO'], path)
if fetch_redirect_response: if fetch_redirect_response:
redirect_response = response.client.get(path, QueryDict(query), redirect_response = response.client.get(path, QueryDict(query),
secure=(scheme == 'https')) secure=(scheme == 'https'))

View File

@ -9,4 +9,6 @@ Django 1.9.6 fixes several bugs in 1.9.5.
Bugfixes Bugfixes
======== ========
* ... * Added support for relative path redirects to
``SimpleTestCase.assertRedirects()`` because Django 1.9 no longer converts
redirects to absolute URIs (:ticket:`26428`).

View File

@ -623,6 +623,14 @@ class ClientTest(TestCase):
# Check some response details # Check some response details
self.assertContains(response, 'This is a test') self.assertContains(response, 'This is a test')
def test_relative_redirect(self):
response = self.client.get('/accounts/')
self.assertRedirects(response, '/accounts/login/')
def test_relative_redirect_no_trailing_slash(self):
response = self.client.get('/accounts/no_trailing_slash')
self.assertRedirects(response, '/accounts/login/')
def test_mass_mail_sending(self): def test_mass_mail_sending(self):
"Test that mass mail is redirected to a dummy outbox during test setup" "Test that mass mail is redirected to a dummy outbox during test setup"

View File

@ -34,6 +34,8 @@ urlpatterns = [
url(r'^nesting_exception_view/$', views.nesting_exception_view), url(r'^nesting_exception_view/$', views.nesting_exception_view),
url(r'^django_project_redirect/$', views.django_project_redirect), url(r'^django_project_redirect/$', views.django_project_redirect),
url(r'^accounts/$', RedirectView.as_view(url='login/')),
url(r'^accounts/no_trailing_slash$', RedirectView.as_view(url='login/')),
url(r'^accounts/login/$', auth_views.login, {'template_name': 'login.html'}), url(r'^accounts/login/$', auth_views.login, {'template_name': 'login.html'}),
url(r'^accounts/logout/$', auth_views.logout), url(r'^accounts/logout/$', auth_views.logout),
] ]