From f0bb3c98cc9e128cb0c1622be9eb41a26794c91f Mon Sep 17 00:00:00 2001
From: Claude Paroz <claude@2xlibre.net>
Date: Mon, 20 Oct 2014 22:32:43 +0200
Subject: [PATCH] Fixed #21740 -- Allowed test client data to be an empty
 string

This fixes a regression introduced by 2a31d00933.
Thanks tony-zhu for the report.
---
 django/test/client.py              |  9 ++++++---
 docs/releases/1.7.1.txt            |  3 +++
 tests/test_client_regress/tests.py | 10 ++++++++++
 3 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/django/test/client.py b/django/test/client.py
index a3a8f21a63..b1ff33e3d3 100644
--- a/django/test/client.py
+++ b/django/test/client.py
@@ -279,8 +279,9 @@ class RequestFactory(object):
     def get(self, path, data=None, secure=False, **extra):
         "Construct a GET request."
 
+        data = {} if data is None else data
         r = {
-            'QUERY_STRING': urlencode(data or {}, doseq=True),
+            'QUERY_STRING': urlencode(data, doseq=True),
         }
         r.update(extra)
         return self.generic('GET', path, secure=secure, **r)
@@ -289,7 +290,8 @@ class RequestFactory(object):
              secure=False, **extra):
         "Construct a POST request."
 
-        post_data = self._encode_data(data or {}, content_type)
+        data = {} if data is None else data
+        post_data = self._encode_data(data, content_type)
 
         return self.generic('POST', path, post_data, content_type,
                             secure=secure, **extra)
@@ -297,8 +299,9 @@ class RequestFactory(object):
     def head(self, path, data=None, secure=False, **extra):
         "Construct a HEAD request."
 
+        data = {} if data is None else data
         r = {
-            'QUERY_STRING': urlencode(data or {}, doseq=True),
+            'QUERY_STRING': urlencode(data, doseq=True),
         }
         r.update(extra)
         return self.generic('HEAD', path, secure=secure, **r)
diff --git a/docs/releases/1.7.1.txt b/docs/releases/1.7.1.txt
index f356d9d8d5..215e2fc211 100644
--- a/docs/releases/1.7.1.txt
+++ b/docs/releases/1.7.1.txt
@@ -129,3 +129,6 @@ Bugfixes
 
 * Fixed :djadmin:`makemigrations` to detect changes to
   :attr:`Meta.db_table <django.db.models.Options.db_table>` (:ticket:`23629`).
+
+* Fixed a regression when feeding the Django test client with an empty data
+  string (:ticket:`21740`).
diff --git a/tests/test_client_regress/tests.py b/tests/test_client_regress/tests.py
index e5dfffe570..b3656e4963 100644
--- a/tests/test_client_regress/tests.py
+++ b/tests/test_client_regress/tests.py
@@ -1228,6 +1228,16 @@ class RequestMethodStringDataTests(TestCase):
         self.assertEqual(response.status_code, 200)
         self.assertEqual(response.content, b'request method: PATCH')
 
+    def test_empty_string_data(self):
+        "Request a view with empty string data via request method GET/POST/HEAD"
+        # Regression test for #21740
+        response = self.client.get('/body/', data='', content_type='application/json')
+        self.assertEqual(response.content, b'')
+        response = self.client.post('/body/', data='', content_type='application/json')
+        self.assertEqual(response.content, b'')
+        response = self.client.head('/body/', data='', content_type='application/json')
+        self.assertEqual(response.content, b'')
+
 
 @override_settings(ROOT_URLCONF='test_client_regress.urls',)
 class QueryStringTests(TestCase):