From ff6b51999868c4d6d4d4b61233f8cc201249b94b Mon Sep 17 00:00:00 2001 From: Oliver Sauder Date: Tue, 7 Jan 2025 21:59:48 +0400 Subject: [PATCH 1/4] Fixed regression that tests using format still work Error only occurred on tests which return no content and use a renderer without charset (e.g. JSONRenderer) --- rest_framework/test.py | 2 +- tests/test_testing.py | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/rest_framework/test.py b/rest_framework/test.py index 730b7708e2..690303fbf6 100644 --- a/rest_framework/test.py +++ b/rest_framework/test.py @@ -195,7 +195,7 @@ def _encode_data(self, data, format=None, content_type=None): ret = renderer.render(data) # Coerce text to bytes if required. - if isinstance(ret, str): + if isinstance(ret, str) and renderer.charset: ret = ret.encode(renderer.charset) return ret, content_type diff --git a/tests/test_testing.py b/tests/test_testing.py index 62dd24dfc6..dd67b058a2 100644 --- a/tests/test_testing.py +++ b/tests/test_testing.py @@ -8,9 +8,9 @@ from django.test import TestCase, override_settings from django.urls import path -from rest_framework import fields, parsers, serializers +from rest_framework import fields, parsers, renderers, serializers, status from rest_framework.authtoken.models import Token -from rest_framework.decorators import api_view, parser_classes +from rest_framework.decorators import api_view, parser_classes, renderer_classes from rest_framework.response import Response from rest_framework.test import ( APIClient, APIRequestFactory, URLPatternsTestCase, force_authenticate @@ -55,6 +55,10 @@ class BasicSerializer(serializers.Serializer): def post_json_view(request): return Response(request.data) +@api_view(['DELETE']) +@renderer_classes((renderers.JSONRenderer, )) +def delete_json_view(request): + return Response(status=status.HTTP_204_NO_CONTENT) @api_view(['POST']) def post_view(request): @@ -69,6 +73,7 @@ def post_view(request): path('redirect-view/', redirect_view), path('redirect-view//', redirect_307_308_view), path('post-json-view/', post_json_view), + path('delete-json-view/', delete_json_view), path('post-view/', post_view), ] @@ -254,6 +259,11 @@ def test_post_encodes_data_based_on_json_content_type(self): assert response.status_code == 200 assert response.data == data + def test_delete_based_on_format(self): + response = self.client.delete('/delete-json-view/', format='json') + assert response.status_code == status.HTTP_204_NO_CONTENT + assert response.data is None + class TestAPIRequestFactory(TestCase): def test_csrf_exempt_by_default(self): From c05926b851bbb3bced20a23278acbdfc7006af3c Mon Sep 17 00:00:00 2001 From: Oliver Sauder Date: Tue, 7 Jan 2025 22:11:41 +0400 Subject: [PATCH 2/4] Fixed linting --- tests/test_testing.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/test_testing.py b/tests/test_testing.py index dd67b058a2..26a6e8ffb9 100644 --- a/tests/test_testing.py +++ b/tests/test_testing.py @@ -10,7 +10,9 @@ from rest_framework import fields, parsers, renderers, serializers, status from rest_framework.authtoken.models import Token -from rest_framework.decorators import api_view, parser_classes, renderer_classes +from rest_framework.decorators import ( + api_view, parser_classes, renderer_classes +) from rest_framework.response import Response from rest_framework.test import ( APIClient, APIRequestFactory, URLPatternsTestCase, force_authenticate @@ -55,11 +57,13 @@ class BasicSerializer(serializers.Serializer): def post_json_view(request): return Response(request.data) + @api_view(['DELETE']) @renderer_classes((renderers.JSONRenderer, )) def delete_json_view(request): return Response(status=status.HTTP_204_NO_CONTENT) + @api_view(['POST']) def post_view(request): serializer = BasicSerializer(data=request.data) From 1b5a84ab8b8c2a662f3c29c5f7abdc8b0d6a3815 Mon Sep 17 00:00:00 2001 From: Oliver Sauder Date: Wed, 8 Jan 2025 10:47:06 +0400 Subject: [PATCH 3/4] Used early return as before --- rest_framework/test.py | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/rest_framework/test.py b/rest_framework/test.py index 690303fbf6..a919f989d2 100644 --- a/rest_framework/test.py +++ b/rest_framework/test.py @@ -150,6 +150,8 @@ def _encode_data(self, data, format=None, content_type=None): """ Encode the data returning a two tuple of (bytes, content_type) """ + if data is None: + return (b'', content_type) assert format is None or content_type is None, ( 'You may not set both `format` and `content_type`.' @@ -161,9 +163,6 @@ def _encode_data(self, data, format=None, content_type=None): except AttributeError: pass - if data is None: - data = '' - # Content type specified explicitly, treat data as a raw bytestring ret = force_bytes(data, settings.DEFAULT_CHARSET) @@ -181,6 +180,7 @@ def _encode_data(self, data, format=None, content_type=None): # Use format and render the data into a bytestring renderer = self.renderer_classes[format]() + ret = renderer.render(data) # Determine the content-type header from the renderer content_type = renderer.media_type @@ -189,14 +189,9 @@ def _encode_data(self, data, format=None, content_type=None): content_type, renderer.charset ) - if data is None: - ret = '' - else: - ret = renderer.render(data) - - # Coerce text to bytes if required. - if isinstance(ret, str) and renderer.charset: - ret = ret.encode(renderer.charset) + # Coerce text to bytes if required. + if isinstance(ret, str): + ret = ret.encode(renderer.charset) return ret, content_type From 77a8015a32572ac7e96a18b2e2162a7ca8b14584 Mon Sep 17 00:00:00 2001 From: Oliver Sauder Date: Wed, 8 Jan 2025 20:54:11 +0400 Subject: [PATCH 4/4] Move ret str check back to where it was --- rest_framework/test.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rest_framework/test.py b/rest_framework/test.py index a919f989d2..c273724b99 100644 --- a/rest_framework/test.py +++ b/rest_framework/test.py @@ -189,9 +189,9 @@ def _encode_data(self, data, format=None, content_type=None): content_type, renderer.charset ) - # Coerce text to bytes if required. - if isinstance(ret, str): - ret = ret.encode(renderer.charset) + # Coerce text to bytes if required. + if isinstance(ret, str): + ret = ret.encode(renderer.charset) return ret, content_type pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy