1+ import itertools
12from io import BytesIO
3+ from unittest .mock import patch
24
35import django
46from django .contrib .auth .models import User
7+ from django .http import HttpResponseRedirect
58from django .shortcuts import redirect
69from django .test import TestCase , override_settings
710from django .urls import path
1417)
1518
1619
17- @api_view (['GET' , 'POST' ])
20+ @api_view (['GET' , 'POST' , 'PUT' , 'PATCH' , 'DELETE' , 'OPTIONS' ])
1821def view (request ):
1922 return Response ({
2023 'auth' : request .META .get ('HTTP_AUTHORIZATION' , b'' ),
@@ -36,6 +39,11 @@ def redirect_view(request):
3639 return redirect ('/view/' )
3740
3841
42+ @api_view (['GET' , 'POST' , 'PUT' , 'PATCH' , 'DELETE' , 'OPTIONS' ])
43+ def redirect_307_308_view (request , code ):
44+ return HttpResponseRedirect ('/view/' , status = code )
45+
46+
3947class BasicSerializer (serializers .Serializer ):
4048 flag = fields .BooleanField (default = lambda : True )
4149
@@ -51,6 +59,7 @@ def post_view(request):
5159 path ('view/' , view ),
5260 path ('session-view/' , session_view ),
5361 path ('redirect-view/' , redirect_view ),
62+ path ('redirect-view/<int:code>/' , redirect_307_308_view ),
5463 path ('post-view/' , post_view )
5564]
5665
@@ -155,6 +164,24 @@ def test_follow_redirect(self):
155164 assert response .redirect_chain is not None
156165 assert response .status_code == 200
157166
167+ def test_follow_307_308_preserve_kwargs (self , * mocked_methods ):
168+ """
169+ Follow redirect by setting follow argument, and make sure the following
170+ method called with appropriate kwargs.
171+ """
172+ methods = ('get' , 'post' , 'put' , 'patch' , 'delete' , 'options' )
173+ codes = (307 , 308 )
174+ for method , code in itertools .product (methods , codes ):
175+ subtest_ctx = self .subTest (method = method , code = code )
176+ patch_ctx = patch .object (self .client , method , side_effect = getattr (self .client , method ))
177+ with subtest_ctx , patch_ctx as req_method :
178+ kwargs = {'data' : {'example' : 'test' }, 'format' : 'json' }
179+ response = req_method ('/redirect-view/%s/' % code , follow = True , ** kwargs )
180+ assert response .redirect_chain is not None
181+ assert response .status_code == 200
182+ for _ , call_args , call_kwargs in req_method .mock_calls :
183+ assert all (call_kwargs [k ] == kwargs [k ] for k in kwargs if k in call_kwargs )
184+
158185 def test_invalid_multipart_data (self ):
159186 """
160187 MultiPart encoding cannot support nested data, so raise a helpful
0 commit comments