1
0
mirror of https://github.com/django/django.git synced 2025-10-26 07:06:08 +00:00

Fixed #4476 -- Added a `follow` option to the test client request methods. This implements browser-like behavior for the test client, following redirect chains when a 30X response is received. Thanks to Marc Fargas and Keith Bussell for their work on this.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@9911 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Russell Keith-Magee
2009-02-27 13:14:59 +00:00
parent e20f09c2d0
commit e735fe7160
7 changed files with 298 additions and 76 deletions

View File

@@ -43,7 +43,7 @@ def disable_transaction_methods():
transaction.savepoint_commit = nop
transaction.savepoint_rollback = nop
transaction.enter_transaction_management = nop
transaction.leave_transaction_management = nop
transaction.leave_transaction_management = nop
def restore_transaction_methods():
transaction.commit = real_commit
@@ -198,7 +198,7 @@ class DocTestRunner(doctest.DocTestRunner):
# Rollback, in case of database errors. Otherwise they'd have
# side effects on other tests.
transaction.rollback_unless_managed()
class TransactionTestCase(unittest.TestCase):
def _pre_setup(self):
"""Performs any pre-test setup. This includes:
@@ -242,7 +242,7 @@ class TransactionTestCase(unittest.TestCase):
import sys
result.addError(self, sys.exc_info())
return
super(TransactionTestCase, self).__call__(result)
super(TransactionTestCase, self).__call__(result)
try:
self._post_teardown()
except (KeyboardInterrupt, SystemExit):
@@ -263,7 +263,7 @@ class TransactionTestCase(unittest.TestCase):
def _fixture_teardown(self):
pass
def _urlconf_teardown(self):
def _urlconf_teardown(self):
if hasattr(self, '_old_root_urlconf'):
settings.ROOT_URLCONF = self._old_root_urlconf
clear_url_caches()
@@ -276,25 +276,48 @@ class TransactionTestCase(unittest.TestCase):
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)))
url = response['Location']
scheme, netloc, path, query, fragment = urlsplit(url)
if hasattr(response, 'redirect_chain'):
# The request was a followed redirect
self.assertTrue(len(response.redirect_chain) > 0,
("Response didn't redirect as expected: Response code was %d"
" (expected %d)" % (response.status_code, status_code)))
self.assertEqual(response.redirect_chain[0][1], status_code,
("Initial response didn't redirect as expected: Response code was %d"
" (expected %d)" % (response.redirect_chain[0][1], status_code)))
url, status_code = response.redirect_chain[-1]
self.assertEqual(response.status_code, target_status_code,
("Response didn't redirect as expected: Final Response code was %d"
" (expected %d)" % (response.status_code, target_status_code)))
else:
# Not a followed redirect
self.assertEqual(response.status_code, status_code,
("Response didn't redirect as expected: Response code was %d"
" (expected %d)" % (response.status_code, status_code)))
url = response['Location']
scheme, netloc, path, query, fragment = urlsplit(url)
redirect_response = response.client.get(path, QueryDict(query))
# Get the redirection page, using the same client that was used
# to obtain the original response.
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))
e_scheme, e_netloc, e_path, e_query, e_fragment = urlsplit(expected_url)
if not (e_scheme or e_netloc):
expected_url = urlunsplit(('http', host or 'testserver', e_path,
e_query, e_fragment))
e_query, e_fragment))
self.assertEqual(url, expected_url,
"Response redirected to '%s', expected '%s'" % (url, expected_url))
# Get the redirection page, using the same client that was used
# to obtain the original response.
redirect_response = response.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))
def assertContains(self, response, text, count=None, status_code=200):
"""
@@ -401,15 +424,15 @@ class TransactionTestCase(unittest.TestCase):
class TestCase(TransactionTestCase):
"""
Does basically the same as TransactionTestCase, but surrounds every test
with a transaction, monkey-patches the real transaction management routines to
do nothing, and rollsback the test transaction at the end of the test. You have
with a transaction, monkey-patches the real transaction management routines to
do nothing, and rollsback the test transaction at the end of the test. You have
to use TransactionTestCase, if you need transaction management inside a test.
"""
def _fixture_setup(self):
if not settings.DATABASE_SUPPORTS_TRANSACTIONS:
return super(TestCase, self)._fixture_setup()
transaction.enter_transaction_management()
transaction.managed(True)
disable_transaction_methods()
@@ -426,7 +449,7 @@ class TestCase(TransactionTestCase):
def _fixture_teardown(self):
if not settings.DATABASE_SUPPORTS_TRANSACTIONS:
return super(TestCase, self)._fixture_teardown()
restore_transaction_methods()
transaction.rollback()
transaction.leave_transaction_management()