From 293f7a21147ad94c92c7d5b3f33cbab2f87b001b Mon Sep 17 00:00:00 2001
From: Julien Phalip <jphalip@gmail.com>
Date: Sat, 2 Feb 2013 18:22:40 -0800
Subject: [PATCH] Fixed #17797 -- Enabled support for PATCH requests in the
 dummy test client. Thanks to pfarmer for the suggestion and initial patch.

---
 django/test/client.py                            | 16 ++++++++++++++++
 docs/topics/testing/overview.txt                 |  8 ++++++++
 .../regressiontests/test_client_regress/tests.py | 15 +++++++++++++++
 3 files changed, 39 insertions(+)

diff --git a/django/test/client.py b/django/test/client.py
index 6bdc1cf3d3..bb0f25e108 100644
--- a/django/test/client.py
+++ b/django/test/client.py
@@ -319,6 +319,11 @@ class RequestFactory(object):
         "Construct a PUT request."
         return self.generic('PUT', path, data, content_type, **extra)
 
+    def patch(self, path, data='', content_type='application/octet-stream',
+            **extra):
+        "Construct a PATCH request."
+        return self.generic('PATCH', path, data, content_type, **extra)
+
     def delete(self, path, data='', content_type='application/octet-stream',
             **extra):
         "Construct a DELETE request."
@@ -496,6 +501,17 @@ class Client(RequestFactory):
             response = self._handle_redirects(response, **extra)
         return response
 
+    def patch(self, path, data='', content_type='application/octet-stream',
+            follow=False, **extra):
+        """
+        Send a resource to the server using PATCH.
+        """
+        response = super(Client, self).patch(
+            path, data=data, content_type=content_type, **extra)
+        if follow:
+            response = self._handle_redirects(response, **extra)
+        return response
+
     def delete(self, path, data='', content_type='application/octet-stream',
             follow=False, **extra):
         """
diff --git a/docs/topics/testing/overview.txt b/docs/topics/testing/overview.txt
index 5739061dd1..3b2babd302 100644
--- a/docs/topics/testing/overview.txt
+++ b/docs/topics/testing/overview.txt
@@ -633,6 +633,14 @@ Use the ``django.test.client.Client`` class to make requests.
         The ``follow`` and ``extra`` arguments act the same as for
         :meth:`Client.get`.
 
+    .. method:: Client.patch(path, data='', content_type='application/octet-stream', follow=False, **extra)
+
+        Makes a PATCH request on the provided ``path`` and returns a
+        ``Response`` object. Useful for testing RESTful interfaces.
+
+        The ``follow`` and ``extra`` arguments act the same as for
+        :meth:`Client.get`.
+
     .. method:: Client.delete(path, data='', content_type='application/octet-stream', follow=False, **extra)
 
         Makes an DELETE request on the provided ``path`` and returns a
diff --git a/tests/regressiontests/test_client_regress/tests.py b/tests/regressiontests/test_client_regress/tests.py
index 5ba5d3c4b3..c52715239b 100644
--- a/tests/regressiontests/test_client_regress/tests.py
+++ b/tests/regressiontests/test_client_regress/tests.py
@@ -783,6 +783,13 @@ class RequestMethodTests(TestCase):
         self.assertEqual(response.status_code, 200)
         self.assertEqual(response.content, b'request method: DELETE')
 
+    def test_patch(self):
+        "Request a view via request method PATCH"
+        response = self.client.patch('/test_client_regress/request_methods/')
+        self.assertEqual(response.status_code, 200)
+        self.assertEqual(response.content, b'request method: PATCH')
+
+
 class RequestMethodStringDataTests(TestCase):
     def test_post(self):
         "Request a view with string data via request method POST"
@@ -800,6 +807,14 @@ class RequestMethodStringDataTests(TestCase):
         self.assertEqual(response.status_code, 200)
         self.assertEqual(response.content, b'request method: PUT')
 
+    def test_patch(self):
+        "Request a view with string data via request method PATCH"
+        # Regression test for #17797
+        data = u'{"test": "json"}'
+        response = self.client.patch('/test_client_regress/request_methods/', data=data, content_type='application/json')
+        self.assertEqual(response.status_code, 200)
+        self.assertEqual(response.content, b'request method: PATCH')
+
 class QueryStringTests(TestCase):
     def test_get_like_requests(self):
         # See: https://code.djangoproject.com/ticket/10571.