Skip to content

Commit 35411fd

Browse files
committed
[1.2.X] Fixed #14116 -- Added a flag to enable CSRF checks in the test client. Thanks to [email protected] for the suggestion.
Backport of r13640 from trunk. git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.2.X@13642 bcc190cf-cafb-0310-a4f2-bffc1f526a37
1 parent 188c6b3 commit 35411fd

File tree

4 files changed

+51
-3
lines changed

4 files changed

+51
-3
lines changed

django/test/client.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ class ClientHandler(BaseHandler):
5555
Uses the WSGI interface to compose requests, but returns
5656
the raw HttpResponse object
5757
"""
58+
def __init__(self, enforce_csrf_checks=True, *args, **kwargs):
59+
self.enforce_csrf_checks = enforce_csrf_checks
60+
super(ClientHandler, self).__init__(*args, **kwargs)
61+
5862
def __call__(self, environ):
5963
from django.conf import settings
6064
from django.core import signals
@@ -71,7 +75,7 @@ def __call__(self, environ):
7175
# CsrfViewMiddleware. This makes life easier, and is probably
7276
# required for backwards compatibility with external tests against
7377
# admin views.
74-
request._dont_enforce_csrf_checks = True
78+
request._dont_enforce_csrf_checks = not self.enforce_csrf_checks
7579
response = self.get_response(request)
7680

7781
# Apply response middleware.
@@ -169,8 +173,8 @@ class Client(object):
169173
contexts and templates produced by a view, rather than the
170174
HTML rendered to the end-user.
171175
"""
172-
def __init__(self, **defaults):
173-
self.handler = ClientHandler()
176+
def __init__(self, enforce_csrf_checks=False, **defaults):
177+
self.handler = ClientHandler(enforce_csrf_checks)
174178
self.defaults = defaults
175179
self.cookies = SimpleCookie()
176180
self.exc_info = None

docs/ref/contrib/csrf.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,13 @@ set a flag on requests which relaxes the middleware and the ``csrf_protect``
398398
decorator so that they no longer rejects requests. In every other respect
399399
(e.g. sending cookies etc.), they behave the same.
400400

401+
If, for some reason, you *want* the test client to perform CSRF
402+
checks, you can create an instance of the test client that enforces
403+
CSRF checks::
404+
405+
>>> from django.test import Client
406+
>>> csrf_client = Client(enforce_csrf_checks=True)
407+
401408
Limitations
402409
===========
403410

docs/topics/testing.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,19 @@ Note a few important things about how the test client works:
572572
This black magic (essentially a patching of Django's template system in
573573
memory) only happens during test running.
574574

575+
* By default, the test client will disable any CSRF checks
576+
performed by your site.
577+
578+
If, for some reason, you *want* the test client to perform CSRF
579+
checks, you can create an instance of the test client that
580+
enforces CSRF checks. To do this, pass in the
581+
``enforce_csrf_checks`` argument when you construct your
582+
client::
583+
584+
>>> from django.test import Client
585+
>>> csrf_client = Client(enforce_csrf_checks=True)
586+
587+
575588
.. _urllib: http://docs.python.org/library/urllib.html
576589
.. _urllib2: http://docs.python.org/library/urllib2.html
577590

tests/modeltests/test_client/models.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
2222
"""
2323
from django.test import Client, TestCase
24+
from django.conf import settings
2425
from django.core import mail
2526

2627
class ClientTest(TestCase):
@@ -433,3 +434,26 @@ def test_mass_mail_sending(self):
433434
self.assertEqual(mail.outbox[1].from_email, '[email protected]')
434435
self.assertEqual(mail.outbox[1].to[0], '[email protected]')
435436
self.assertEqual(mail.outbox[1].to[1], '[email protected]')
437+
438+
class CSRFEnabledClientTests(TestCase):
439+
def setUp(self):
440+
# Enable the CSRF middleware for this test
441+
self.old_MIDDLEWARE_CLASSES = settings.MIDDLEWARE_CLASSES
442+
csrf_middleware_class = 'django.middleware.csrf.CsrfViewMiddleware'
443+
if csrf_middleware_class not in settings.MIDDLEWARE_CLASSES:
444+
settings.MIDDLEWARE_CLASSES += (csrf_middleware_class,)
445+
446+
def tearDown(self):
447+
settings.MIDDLEWARE_CLASSES = self.old_MIDDLEWARE_CLASSES
448+
449+
def test_csrf_enabled_client(self):
450+
"A client can be instantiated with CSRF checks enabled"
451+
csrf_client = Client(enforce_csrf_checks=True)
452+
453+
# The normal client allows the post
454+
response = self.client.post('/test_client/post_view/', {})
455+
self.assertEqual(response.status_code, 200)
456+
457+
# The CSRF-enabled client rejects it
458+
response = csrf_client.post('/test_client/post_view/', {})
459+
self.assertEqual(response.status_code, 403)

0 commit comments

Comments
 (0)