Kaydet (Commit) 5ad08583 authored tarafından Russell Keith-Magee's avatar Russell Keith-Magee

Fixed #4968 -- Added assertRedirects handling for paths with GET data. Thanks…

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
üst d09d1428
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): ...@@ -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))
......
...@@ -826,10 +826,10 @@ useful for testing Web applications: ...@@ -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
......
...@@ -86,6 +86,13 @@ class ClientTest(TestCase): ...@@ -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): ...@@ -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): ...@@ -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"
......
...@@ -48,7 +48,12 @@ def raw_post_view(request): ...@@ -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"
......
...@@ -112,6 +112,14 @@ class AssertRedirectsTests(TestCase): ...@@ -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"
......
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