Commit 35411fd7 authored by Russell Keith-Magee's avatar Russell Keith-Magee
Browse files

[1.2.X] Fixed #14116 -- Added a flag to enable CSRF checks in the test client....

[1.2.X] Fixed #14116 -- Added a flag to enable CSRF checks in the test client. Thanks to jon@licq.org 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
parent 188c6b3e
Loading
Loading
Loading
Loading
+7 −3
Original line number Diff line number Diff line
@@ -55,6 +55,10 @@ class ClientHandler(BaseHandler):
    Uses the WSGI interface to compose requests, but returns
    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):
        from django.conf import settings
        from django.core import signals
@@ -71,7 +75,7 @@ class ClientHandler(BaseHandler):
            # CsrfViewMiddleware.  This makes life easier, and is probably
            # required for backwards compatibility with external tests against
            # admin views.
            request._dont_enforce_csrf_checks = True
            request._dont_enforce_csrf_checks = not self.enforce_csrf_checks
            response = self.get_response(request)

            # Apply response middleware.
@@ -169,8 +173,8 @@ class Client(object):
    contexts and templates produced by a view, rather than the
    HTML rendered to the end-user.
    """
    def __init__(self, **defaults):
        self.handler = ClientHandler()
    def __init__(self, enforce_csrf_checks=False, **defaults):
        self.handler = ClientHandler(enforce_csrf_checks)
        self.defaults = defaults
        self.cookies = SimpleCookie()
        self.exc_info = None
+7 −0
Original line number Diff line number Diff line
@@ -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
(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
===========

+13 −0
Original line number Diff line number Diff line
@@ -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
      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
.. _urllib2: http://docs.python.org/library/urllib2.html

+24 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ rather than the HTML rendered to the end-user.

"""
from django.test import Client, TestCase
from django.conf import settings
from django.core import mail

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].to[0], 'second@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)