Fixed #4968 -- Added assertRedirects handling for paths with GET data. Thanks for the patch, Ivan Sagalaev.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@6031 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Russell Keith-Magee 2007-08-31 11:37:28 +00:00
parent d09d1428f8
commit 5ad08583e1
5 changed files with 41 additions and 12 deletions

View File

@ -1,5 +1,6 @@
import re, unittest import re, unittest
from urlparse import urlparse from urlparse import urlsplit
from django.http import QueryDict
from django.db import transaction from django.db import transaction
from django.core import mail from django.core import mail
from django.core.management import call_command from django.core.management import call_command
@ -60,18 +61,26 @@ class TestCase(unittest.TestCase):
self._pre_setup() self._pre_setup()
super(TestCase, self).__call__(result) super(TestCase, self).__call__(result)
def assertRedirects(self, response, expected_path, status_code=302, target_status_code=200): def assertRedirects(self, response, expected_url, status_code=302, target_status_code=200):
"""Assert that a response redirected to a specific URL, and that the """Assert that a response redirected to a specific URL, and that the
redirect URL can be loaded. redirect URL can be loaded.
Note that assertRedirects won't work for external links since it uses
TestClient to do a request.
""" """
self.assertEqual(response.status_code, status_code, self.assertEqual(response.status_code, status_code,
"Response didn't redirect as expected: Response code was %d (expected %d)" % "Response didn't redirect as expected: Response code was %d (expected %d)" %
(response.status_code, status_code)) (response.status_code, status_code))
scheme, netloc, path, params, query, fragment = urlparse(response['Location']) scheme, netloc, path, query, fragment = urlsplit(response['Location'])
self.assertEqual(path, expected_path, url = path
"Response redirected to '%s', expected '%s'" % (path, expected_path)) if query:
redirect_response = self.client.get(path) url += '?' + query
if fragment:
url += '#' + fragment
self.assertEqual(url, expected_url,
"Response redirected to '%s', expected '%s'" % (url, expected_url))
redirect_response = self.client.get(path, QueryDict(query))
self.assertEqual(redirect_response.status_code, target_status_code, self.assertEqual(redirect_response.status_code, target_status_code,
"Couldn't retrieve redirection page '%s': response code was %d (expected %d)" % "Couldn't retrieve redirection page '%s': response code was %d (expected %d)" %
(path, redirect_response.status_code, target_status_code)) (path, redirect_response.status_code, target_status_code))

View File

@ -826,10 +826,10 @@ useful for testing Web applications:
Asserts that the template with the given name was *not* used in rendering Asserts that the template with the given name was *not* used in rendering
the response. the response.
``assertRedirects(response, expected_path, status_code=302, target_status_code=200)`` ``assertRedirects(response, expected_url, status_code=302, target_status_code=200)``
Asserts that the response return a ``status_code`` redirect status, Asserts that the response return a ``status_code`` redirect status,
it redirected to ``expected_path`` and the subsequent page was received with it redirected to ``expected_url`` (including any GET data), and the subsequent
``target_status_code``. page was received with ``target_status_code``.
``assertTemplateUsed(response, template_name)`` ``assertTemplateUsed(response, template_name)``
Asserts that the template with the given name was used in rendering the Asserts that the template with the given name was used in rendering the

View File

@ -86,6 +86,13 @@ class ClientTest(TestCase):
# Check that the response was a 302 (redirect) # Check that the response was a 302 (redirect)
self.assertRedirects(response, '/test_client/get_view/') self.assertRedirects(response, '/test_client/get_view/')
def test_redirect_with_query(self):
"GET a URL that redirects with given GET parameters"
response = self.client.get('/test_client/redirect_view/', {'var': 'value'})
# Check if parameters are intact
self.assertRedirects(response, '/test_client/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"
@ -224,7 +231,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('/test_client/login_protected_view/') response = self.client.get('/test_client/login_protected_view/')
self.assertRedirects(response, '/accounts/login/') self.assertRedirects(response, '/accounts/login/?next=/test_client/login_protected_view/')
# Log in # Log in
self.client.login(username='testclient', password='password') self.client.login(username='testclient', password='password')
@ -261,7 +268,7 @@ class ClientTest(TestCase):
# Request a page that requires a login # Request a page that requires a login
response = self.client.get('/test_client/login_protected_view/') response = self.client.get('/test_client/login_protected_view/')
self.assertRedirects(response, '/accounts/login/') self.assertRedirects(response, '/accounts/login/?next=/test_client/login_protected_view/')
def test_session_modifying_view(self): def test_session_modifying_view(self):
"Request a page that modifies the session" "Request a page that modifies the session"

View File

@ -48,7 +48,12 @@ def raw_post_view(request):
def redirect_view(request): def redirect_view(request):
"A view that redirects all requests to the GET view" "A view that redirects all requests to the GET view"
return HttpResponseRedirect('/test_client/get_view/') if request.GET:
from urllib import urlencode
query = '?' + urlencode(request.GET, True)
else:
query = ''
return HttpResponseRedirect('/test_client/get_view/' + query)
def double_redirect_view(request): def double_redirect_view(request):
"A view that redirects all requests to a redirection view" "A view that redirects all requests to a redirection view"

View File

@ -112,6 +112,14 @@ class AssertRedirectsTests(TestCase):
self.assertRedirects(response, '/test_client/get_view/') self.assertRedirects(response, '/test_client/get_view/')
except AssertionError, e: except AssertionError, e:
self.assertEquals(str(e), "Response didn't redirect as expected: Response code was 301 (expected 302)") self.assertEquals(str(e), "Response didn't redirect as expected: Response code was 301 (expected 302)")
def test_lost_query(self):
"An assertion is raised if the redirect location doesn't preserve GET parameters"
response = self.client.get('/test_client/redirect_view/', {'var': 'value'})
try:
self.assertRedirects(response, '/test_client/get_view/')
except AssertionError, e:
self.assertEquals(str(e), "Response redirected to '/test_client/get_view/?var=value', expected '/test_client/get_view/'")
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"