1
0
mirror of https://github.com/django/django.git synced 2025-02-23 07:55:07 +00:00

Fixed #14116 -- Added a flag to enable CSRF checks in the test client. Thanks to jon@licq.org for the suggestion.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@13640 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Russell Keith-Magee 2010-08-27 13:54:13 +00:00
parent 88e83ee472
commit 8ce4a1991a
4 changed files with 51 additions and 3 deletions

View File

@ -55,6 +55,10 @@ class ClientHandler(BaseHandler):
Uses the WSGI interface to compose requests, but returns Uses the WSGI interface to compose requests, but returns
the raw HttpResponse object the raw HttpResponse object
""" """
def __init__(self, enforce_csrf_checks=True, *args, **kwargs):
self.enforce_csrf_checks = enforce_csrf_checks
super(ClientHandler, self).__init__(*args, **kwargs)
def __call__(self, environ): def __call__(self, environ):
from django.conf import settings from django.conf import settings
from django.core import signals from django.core import signals
@ -71,7 +75,7 @@ class ClientHandler(BaseHandler):
# CsrfViewMiddleware. This makes life easier, and is probably # CsrfViewMiddleware. This makes life easier, and is probably
# required for backwards compatibility with external tests against # required for backwards compatibility with external tests against
# admin views. # admin views.
request._dont_enforce_csrf_checks = True request._dont_enforce_csrf_checks = not self.enforce_csrf_checks
response = self.get_response(request) response = self.get_response(request)
# Apply response middleware. # Apply response middleware.
@ -169,8 +173,8 @@ class Client(object):
contexts and templates produced by a view, rather than the contexts and templates produced by a view, rather than the
HTML rendered to the end-user. HTML rendered to the end-user.
""" """
def __init__(self, **defaults): def __init__(self, enforce_csrf_checks=False, **defaults):
self.handler = ClientHandler() self.handler = ClientHandler(enforce_csrf_checks)
self.defaults = defaults self.defaults = defaults
self.cookies = SimpleCookie() self.cookies = SimpleCookie()
self.exc_info = None self.exc_info = None

View File

@ -398,6 +398,13 @@ set a flag on requests which relaxes the middleware and the ``csrf_protect``
decorator so that they no longer rejects requests. In every other respect decorator so that they no longer rejects requests. In every other respect
(e.g. sending cookies etc.), they behave the same. (e.g. sending cookies etc.), they behave the same.
If, for some reason, you *want* the test client to perform CSRF
checks, you can create an instance of the test client that enforces
CSRF checks::
>>> from django.test import Client
>>> csrf_client = Client(enforce_csrf_checks=True)
Limitations Limitations
=========== ===========

View File

@ -572,6 +572,19 @@ Note a few important things about how the test client works:
This black magic (essentially a patching of Django's template system in This black magic (essentially a patching of Django's template system in
memory) only happens during test running. memory) only happens during test running.
* By default, the test client will disable any CSRF checks
performed by your site.
If, for some reason, you *want* the test client to perform CSRF
checks, you can create an instance of the test client that
enforces CSRF checks. To do this, pass in the
``enforce_csrf_checks`` argument when you construct your
client::
>>> from django.test import Client
>>> csrf_client = Client(enforce_csrf_checks=True)
.. _urllib: http://docs.python.org/library/urllib.html .. _urllib: http://docs.python.org/library/urllib.html
.. _urllib2: http://docs.python.org/library/urllib2.html .. _urllib2: http://docs.python.org/library/urllib2.html

View File

@ -21,6 +21,7 @@ rather than the HTML rendered to the end-user.
""" """
from django.test import Client, TestCase from django.test import Client, TestCase
from django.conf import settings
from django.core import mail from django.core import mail
class ClientTest(TestCase): class ClientTest(TestCase):
@ -433,3 +434,26 @@ class ClientTest(TestCase):
self.assertEqual(mail.outbox[1].from_email, 'from@example.com') self.assertEqual(mail.outbox[1].from_email, 'from@example.com')
self.assertEqual(mail.outbox[1].to[0], 'second@example.com') self.assertEqual(mail.outbox[1].to[0], 'second@example.com')
self.assertEqual(mail.outbox[1].to[1], 'third@example.com') self.assertEqual(mail.outbox[1].to[1], 'third@example.com')
class CSRFEnabledClientTests(TestCase):
def setUp(self):
# Enable the CSRF middleware for this test
self.old_MIDDLEWARE_CLASSES = settings.MIDDLEWARE_CLASSES
csrf_middleware_class = 'django.middleware.csrf.CsrfViewMiddleware'
if csrf_middleware_class not in settings.MIDDLEWARE_CLASSES:
settings.MIDDLEWARE_CLASSES += (csrf_middleware_class,)
def tearDown(self):
settings.MIDDLEWARE_CLASSES = self.old_MIDDLEWARE_CLASSES
def test_csrf_enabled_client(self):
"A client can be instantiated with CSRF checks enabled"
csrf_client = Client(enforce_csrf_checks=True)
# The normal client allows the post
response = self.client.post('/test_client/post_view/', {})
self.assertEqual(response.status_code, 200)
# The CSRF-enabled client rejects it
response = csrf_client.post('/test_client/post_view/', {})
self.assertEqual(response.status_code, 403)