diff options
| author | Jason Pellerin <jpellerin@gmail.com> | 2006-09-08 16:35:39 +0000 |
|---|---|---|
| committer | Jason Pellerin <jpellerin@gmail.com> | 2006-09-08 16:35:39 +0000 |
| commit | 84f7a2133c4d553a234165bb8cbfaf70681bb028 (patch) | |
| tree | 53d08c1ffc275a4e1d62d7f48ea81172a5919051 /django/test | |
| parent | ae3896cb74d4bc42acaf6fade0d2a57e28045b2a (diff) | |
[multi-db] Merge trunk to [3737]. Some tests still failing.
git-svn-id: http://code.djangoproject.com/svn/django/branches/multiple-db-support@3739 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'django/test')
| -rw-r--r-- | django/test/client.py | 48 | ||||
| -rw-r--r-- | django/test/signals.py | 1 | ||||
| -rw-r--r-- | django/test/simple.py | 4 | ||||
| -rw-r--r-- | django/test/utils.py | 52 |
4 files changed, 74 insertions, 31 deletions
diff --git a/django/test/client.py b/django/test/client.py index 871f6cfb9b..3dfe764a38 100644 --- a/django/test/client.py +++ b/django/test/client.py @@ -1,10 +1,9 @@ from cStringIO import StringIO -from django.contrib.admin.views.decorators import LOGIN_FORM_KEY, _encode_post_data from django.core.handlers.base import BaseHandler from django.core.handlers.wsgi import WSGIRequest from django.dispatch import dispatcher from django.http import urlencode, SimpleCookie -from django.template import signals +from django.test import signals from django.utils.functional import curry class ClientHandler(BaseHandler): @@ -96,7 +95,7 @@ class Client: HTML rendered to the end-user. """ def __init__(self, **defaults): - self.handler = TestHandler() + self.handler = ClientHandler() self.defaults = defaults self.cookie = SimpleCookie() @@ -126,7 +125,7 @@ class Client: data = {} on_template_render = curry(store_rendered_templates, data) dispatcher.connect(on_template_render, signal=signals.template_rendered) - + response = self.handler(environ) # Add any rendered template detail to the response @@ -180,29 +179,38 @@ class Client: def login(self, path, username, password, **extra): """ A specialized sequence of GET and POST to log into a view that - is protected by @login_required or a similar access decorator. + is protected by a @login_required access decorator. - path should be the URL of the login page, or of any page that - is login protected. + path should be the URL of the page that is login protected. - Returns True if login was successful; False if otherwise. + Returns the response from GETting the requested URL after + login is complete. Returns False if login process failed. """ - # First, GET the login page. - # This is required to establish the session. + # First, GET the page that is login protected. + # This page will redirect to the login page. response = self.get(path) - if response.status_code != 200: + if response.status_code != 302: return False + + login_path, data = response['Location'].split('?') + next = data.split('=')[1] - # Set up the block of form data required by the login page. + # Second, GET the login page; required to set up cookies + response = self.get(login_path, **extra) + if response.status_code != 200: + return False + + # Last, POST the login data. form_data = { 'username': username, 'password': password, - 'this_is_the_login_form': 1, - 'post_data': _encode_post_data({LOGIN_FORM_KEY: 1}) + 'next' : next, } - response = self.post(path, data=form_data, **extra) - - # login page should give response 200 (if you requested the login - # page specifically), or 302 (if you requested a login - # protected page, to which the login can redirect). - return response.status_code in (200,302) + response = self.post(login_path, data=form_data, **extra) + + # Login page should 302 redirect to the originally requested page + if response.status_code != 302 or response['Location'] != path: + return False + + # Since we are logged in, request the actual page again + return self.get(path) diff --git a/django/test/signals.py b/django/test/signals.py new file mode 100644 index 0000000000..40748ff4fe --- /dev/null +++ b/django/test/signals.py @@ -0,0 +1 @@ +template_rendered = object()
\ No newline at end of file diff --git a/django/test/simple.py b/django/test/simple.py index 2469f80b3a..043787414e 100644 --- a/django/test/simple.py +++ b/django/test/simple.py @@ -1,6 +1,7 @@ import unittest, doctest from django.conf import settings from django.core import management +from django.test.utils import setup_test_environment, teardown_test_environment from django.test.utils import create_test_db, destroy_test_db from django.test.testcases import OutputChecker, DocTestRunner @@ -51,6 +52,7 @@ def run_tests(module_list, verbosity=1, extra_tests=[]): the module. A list of 'extra' tests may also be provided; these tests will be added to the test suite. """ + setup_test_environment() settings.DEBUG = False suite = unittest.TestSuite() @@ -66,3 +68,5 @@ def run_tests(module_list, verbosity=1, extra_tests=[]): management.syncdb(verbosity, interactive=False) unittest.TextTestRunner(verbosity=verbosity).run(suite) destroy_test_db(old_name, verbosity) + + teardown_test_environment() diff --git a/django/test/utils.py b/django/test/utils.py index bde323fa4e..d7a4a9c963 100644 --- a/django/test/utils.py +++ b/django/test/utils.py @@ -1,11 +1,41 @@ import sys, time from django.conf import settings + from django.db import backend, connect, connection, connection_info, connections +from django.dispatch import dispatcher +from django.test import signals +from django.template import Template # The prefix to put on the default database name when creating # the test database. TEST_DATABASE_PREFIX = 'test_' +def instrumented_test_render(self, context): + """An instrumented Template render method, providing a signal + that can be intercepted by the test system Client + + """ + dispatcher.send(signal=signals.template_rendered, sender=self, template=self, context=context) + return self.nodelist.render(context) + +def setup_test_environment(): + """Perform any global pre-test setup. This involves: + + - Installing the instrumented test renderer + + """ + Template.original_render = Template.render + Template.render = instrumented_test_render + +def teardown_test_environment(): + """Perform any global post-test teardown. This involves: + + - Restoring the original test renderer + + """ + Template.render = Template.original_render + del Template.original_render + def _set_autocommit(connection): "Make sure a connection is in autocommit mode." if hasattr(connection.connection, "autocommit"): @@ -55,12 +85,13 @@ def create_test_db(verbosity=1, autoclobber=False): else: print "Tests cancelled." sys.exit(1) - # Close the old connection - connection.close() + + connection.close() + settings.DATABASE_NAME = TEST_DATABASE_NAME - # Get a cursor (even though we don't need one yet). This has - # the side effect of initializing the test database. - cursor = connection.cursor() + # Get a cursor (even though we don't need one yet). This has + # the side effect of initializing the test database. + cursor = connection.cursor() # Fill OTHER_DATABASES with the TEST_DATABASES settings, # and connect each named connection to the test database, using @@ -87,15 +118,14 @@ def destroy_test_db(old_database_name, old_databases, verbosity=1): # connected to it. if verbosity >= 1: print "Destroying test database..." - if settings.DATABASE_ENGINE != "sqlite3": - connection.close() - TEST_DATABASE_NAME = settings.DATABASE_NAME - settings.DATABASE_NAME = old_database_name + connection.close() + TEST_DATABASE_NAME = settings.DATABASE_NAME + settings.DATABASE_NAME = old_database_name + + if settings.DATABASE_ENGINE != "sqlite3": settings.OTHER_DATABASES = old_databases cursor = connection.cursor() _set_autocommit(connection) time.sleep(1) # To avoid "database is being accessed by other users" errors. cursor.execute("DROP DATABASE %s" % backend.quote_name(TEST_DATABASE_NAME)) connection.close() - - |
