From 5ad08583e166b63fff12fc87fa84528e946ac6ad Mon Sep 17 00:00:00 2001 From: Russell Keith-Magee Date: Fri, 31 Aug 2007 11:37:28 +0000 Subject: [PATCH] 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 --- django/test/testcases.py | 21 +++++++++++++------ docs/testing.txt | 6 +++--- tests/modeltests/test_client/models.py | 11 ++++++++-- tests/modeltests/test_client/views.py | 7 ++++++- .../test_client_regress/models.py | 8 +++++++ 5 files changed, 41 insertions(+), 12 deletions(-) diff --git a/django/test/testcases.py b/django/test/testcases.py index 21c429271c..2ed2e9ba26 100644 --- a/django/test/testcases.py +++ b/django/test/testcases.py @@ -1,5 +1,6 @@ import re, unittest -from urlparse import urlparse +from urlparse import urlsplit +from django.http import QueryDict from django.db import transaction from django.core import mail from django.core.management import call_command @@ -60,18 +61,26 @@ class TestCase(unittest.TestCase): self._pre_setup() 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 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, "Response didn't redirect as expected: Response code was %d (expected %d)" % (response.status_code, status_code)) - scheme, netloc, path, params, query, fragment = urlparse(response['Location']) - self.assertEqual(path, expected_path, - "Response redirected to '%s', expected '%s'" % (path, expected_path)) - redirect_response = self.client.get(path) + scheme, netloc, path, query, fragment = urlsplit(response['Location']) + url = path + if query: + 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, "Couldn't retrieve redirection page '%s': response code was %d (expected %d)" % (path, redirect_response.status_code, target_status_code)) diff --git a/docs/testing.txt b/docs/testing.txt index e27479cc34..bb62273bea 100644 --- a/docs/testing.txt +++ b/docs/testing.txt @@ -826,10 +826,10 @@ useful for testing Web applications: Asserts that the template with the given name was *not* used in rendering 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, - it redirected to ``expected_path`` and the subsequent page was received with - ``target_status_code``. + it redirected to ``expected_url`` (including any GET data), and the subsequent + page was received with ``target_status_code``. ``assertTemplateUsed(response, template_name)`` Asserts that the template with the given name was used in rendering the diff --git a/tests/modeltests/test_client/models.py b/tests/modeltests/test_client/models.py index e1f3987847..200a71f6f9 100644 --- a/tests/modeltests/test_client/models.py +++ b/tests/modeltests/test_client/models.py @@ -86,6 +86,13 @@ class ClientTest(TestCase): # Check that the response was a 302 (redirect) 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): "GET a URL that redirects permanently elsewhere" @@ -224,7 +231,7 @@ class ClientTest(TestCase): # Get the page without logging in. Should result in 302. 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 self.client.login(username='testclient', password='password') @@ -261,7 +268,7 @@ class ClientTest(TestCase): # Request a page that requires a login 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): "Request a page that modifies the session" diff --git a/tests/modeltests/test_client/views.py b/tests/modeltests/test_client/views.py index 81b4a2f283..3fc638b230 100644 --- a/tests/modeltests/test_client/views.py +++ b/tests/modeltests/test_client/views.py @@ -48,7 +48,12 @@ def raw_post_view(request): def redirect_view(request): "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): "A view that redirects all requests to a redirection view" diff --git a/tests/regressiontests/test_client_regress/models.py b/tests/regressiontests/test_client_regress/models.py index e17770cd03..e85544f285 100644 --- a/tests/regressiontests/test_client_regress/models.py +++ b/tests/regressiontests/test_client_regress/models.py @@ -112,6 +112,14 @@ class AssertRedirectsTests(TestCase): self.assertRedirects(response, '/test_client/get_view/') except AssertionError, e: 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): "An assertion is raised if the response redirects to another target"