diff --git a/django/test/client.py b/django/test/client.py index 129377c232..05d3d78603 100644 --- a/django/test/client.py +++ b/django/test/client.py @@ -34,6 +34,8 @@ __all__ = ('Client', 'RedirectCycleError', 'RequestFactory', 'encode_file', 'enc BOUNDARY = 'BoUnDaRyStRiNg' MULTIPART_CONTENT = 'multipart/form-data; boundary=%s' % BOUNDARY CONTENT_TYPE_RE = re.compile(r'.*; charset=([\w\d-]+);?') +# JSON Vendor Tree spec: https://tools.ietf.org/html/rfc6838#section-3.2 +JSON_CONTENT_TYPE_RE = re.compile(r'^application\/(vnd\..+\+)?json$') class RedirectCycleError(Exception): @@ -690,7 +692,7 @@ class Client(RequestFactory): def _parse_json(self, response, **extra): if not hasattr(response, '_json'): - if 'application/json' not in response.get('Content-Type'): + if not JSON_CONTENT_TYPE_RE.match(response.get('Content-Type')): raise ValueError( 'Content-Type header is "{0}", not "application/json"' .format(response.get('Content-Type')) diff --git a/tests/test_client_regress/tests.py b/tests/test_client_regress/tests.py index 7a633ee7a3..2c1a9b346a 100644 --- a/tests/test_client_regress/tests.py +++ b/tests/test_client_regress/tests.py @@ -1209,6 +1209,12 @@ class RequestMethodStringDataTests(SimpleTestCase): response = self.client.get('/json_response/') self.assertEqual(response.json(), {'key': 'value'}) + def test_json_vendor(self): + for content_type in ('application/vnd.api+json', 'application/vnd.api.foo+json'): + response = self.client.get('/json_response/', {'content_type': content_type}) + self.assertEqual(response['Content-Type'], content_type) + self.assertEqual(response.json(), {'key': 'value'}) + def test_json_multiple_access(self): response = self.client.get('/json_response/') self.assertIs(response.json(), response.json()) diff --git a/tests/test_client_regress/views.py b/tests/test_client_regress/views.py index a50b0e1ed3..ce60c0398c 100644 --- a/tests/test_client_regress/views.py +++ b/tests/test_client_regress/views.py @@ -106,7 +106,9 @@ def return_undecodable_binary(request): def return_json_response(request): - return JsonResponse({'key': 'value'}) + content_type = request.GET.get('content_type') + kwargs = {'content_type': content_type} if content_type else {} + return JsonResponse({'key': 'value'}, **kwargs) def return_json_file(request):