From fe01404bb9f276446fc42390242da25122f91663 Mon Sep 17 00:00:00 2001
From: Claude Paroz <claude@2xlibre.net>
Date: Thu, 11 Apr 2013 10:36:12 +0200
Subject: [PATCH] Fixed #20237 -- Reenabled assertContains with binary
 parameter

Thanks Baptiste Mispelon for the review.
---
 django/test/testcases.py           | 13 +++++++++----
 tests/test_client_regress/tests.py |  7 +++++++
 tests/test_client_regress/urls.py  |  1 +
 tests/test_client_regress/views.py |  5 +++++
 4 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/django/test/testcases.py b/django/test/testcases.py
index a55bb6080d..358cb3f37d 100644
--- a/django/test/testcases.py
+++ b/django/test/testcases.py
@@ -614,12 +614,14 @@ class TransactionTestCase(SimpleTestCase):
         self.assertEqual(response.status_code, status_code,
             msg_prefix + "Couldn't retrieve content: Response code was %d"
             " (expected %d)" % (response.status_code, status_code))
-        text = force_text(text, encoding=response._charset)
+
         if response.streaming:
             content = b''.join(response.streaming_content)
         else:
             content = response.content
-        content = content.decode(response._charset)
+        if not isinstance(text, bytes) or html:
+            text = force_text(text, encoding=response._charset)
+            content = content.decode(response._charset)
         if html:
             content = assert_and_parse_html(self, content, None,
                 "Response's content is not valid HTML:")
@@ -654,8 +656,11 @@ class TransactionTestCase(SimpleTestCase):
         self.assertEqual(response.status_code, status_code,
             msg_prefix + "Couldn't retrieve content: Response code was %d"
             " (expected %d)" % (response.status_code, status_code))
-        text = force_text(text, encoding=response._charset)
-        content = response.content.decode(response._charset)
+
+        content = response.content
+        if not isinstance(text, bytes) or html:
+            text = force_text(text, encoding=response._charset)
+            content = content.decode(response._charset)
         if html:
             content = assert_and_parse_html(self, content, None,
                 'Response\'s content is not valid HTML:')
diff --git a/tests/test_client_regress/tests.py b/tests/test_client_regress/tests.py
index 9972d67d7d..fe0a4109b5 100644
--- a/tests/test_client_regress/tests.py
+++ b/tests/test_client_regress/tests.py
@@ -131,6 +131,13 @@ class AssertContainsTests(TestCase):
         self.assertNotContains(r, 'はたけ')
         self.assertNotContains(r, b'\xe3\x81\xaf\xe3\x81\x9f\xe3\x81\x91'.decode('utf-8'))
 
+    def test_binary_contains(self):
+        r = self.client.get('/test_client_regress/check_binary/')
+        self.assertContains(r, b'PDF document')
+        with self.assertRaises(AssertionError):
+            self.assertContains(r, b'PDF document', count=2)
+        self.assertNotContains(r, b'ODF document')
+
     def test_nontext_contains(self):
         r = self.client.get('/test_client_regress/no_template_view/')
         self.assertContains(r, ugettext_lazy('once'))
diff --git a/tests/test_client_regress/urls.py b/tests/test_client_regress/urls.py
index d869c234eb..1332537d57 100644
--- a/tests/test_client_regress/urls.py
+++ b/tests/test_client_regress/urls.py
@@ -28,6 +28,7 @@ urlpatterns = patterns('',
     (r'^check_session/$', views.check_session_view),
     (r'^request_methods/$', views.request_methods_view),
     (r'^check_unicode/$', views.return_unicode),
+    (r'^check_binary/$', views.return_undecodable_binary),
     (r'^parse_unicode_json/$', views.return_json_file),
     (r'^check_headers/$', views.check_headers),
     (r'^check_headers_redirect/$', RedirectView.as_view(url='/test_client_regress/check_headers/')),
diff --git a/tests/test_client_regress/views.py b/tests/test_client_regress/views.py
index 9b0654806b..7e86ffd8ca 100644
--- a/tests/test_client_regress/views.py
+++ b/tests/test_client_regress/views.py
@@ -70,6 +70,11 @@ def request_methods_view(request):
 def return_unicode(request):
     return render_to_response('unicode.html')
 
+def return_undecodable_binary(request):
+    return HttpResponse(
+        b'%PDF-1.4\r\n%\x93\x8c\x8b\x9e ReportLab Generated PDF document http://www.reportlab.com'
+    )
+
 def return_json_file(request):
     "A view that parses and returns a JSON string as a file."
     match = CONTENT_TYPE_RE.match(request.META['CONTENT_TYPE'])