1
+ import itertools
1
2
from io import BytesIO
3
+ from unittest .mock import patch
2
4
3
5
import django
4
6
from django .contrib .auth .models import User
7
+ from django .http import HttpResponseRedirect
5
8
from django .shortcuts import redirect
6
9
from django .test import TestCase , override_settings
7
10
from django .urls import path
14
17
)
15
18
16
19
17
- @api_view (['GET' , 'POST' ])
20
+ @api_view (['GET' , 'POST' , 'PUT' , 'PATCH' , 'DELETE' , 'OPTIONS' ])
18
21
def view (request ):
19
22
return Response ({
20
23
'auth' : request .META .get ('HTTP_AUTHORIZATION' , b'' ),
@@ -36,6 +39,11 @@ def redirect_view(request):
36
39
return redirect ('/view/' )
37
40
38
41
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
+
39
47
class BasicSerializer (serializers .Serializer ):
40
48
flag = fields .BooleanField (default = lambda : True )
41
49
@@ -51,6 +59,7 @@ def post_view(request):
51
59
path ('view/' , view ),
52
60
path ('session-view/' , session_view ),
53
61
path ('redirect-view/' , redirect_view ),
62
+ path ('redirect-view/<int:code>/' , redirect_307_308_view ),
54
63
path ('post-view/' , post_view )
55
64
]
56
65
@@ -146,41 +155,32 @@ def test_follow_redirect(self):
146
155
"""
147
156
Follow redirect by setting follow argument.
148
157
"""
149
- response = self .client .get ('/redirect-view/' )
150
- assert response .status_code == 302
151
- response = self .client .get ('/redirect-view/' , follow = True )
152
- assert response .redirect_chain is not None
153
- assert response .status_code == 200
154
-
155
- response = self .client .post ('/redirect-view/' )
156
- assert response .status_code == 302
157
- response = self .client .post ('/redirect-view/' , follow = True )
158
- assert response .redirect_chain is not None
159
- assert response .status_code == 200
160
-
161
- response = self .client .put ('/redirect-view/' )
162
- assert response .status_code == 302
163
- response = self .client .put ('/redirect-view/' , follow = True )
164
- assert response .redirect_chain is not None
165
- assert response .status_code == 200
166
-
167
- response = self .client .patch ('/redirect-view/' )
168
- assert response .status_code == 302
169
- response = self .client .patch ('/redirect-view/' , follow = True )
170
- assert response .redirect_chain is not None
171
- assert response .status_code == 200
172
-
173
- response = self .client .delete ('/redirect-view/' )
174
- assert response .status_code == 302
175
- response = self .client .delete ('/redirect-view/' , follow = True )
176
- assert response .redirect_chain is not None
177
- assert response .status_code == 200
178
-
179
- response = self .client .options ('/redirect-view/' )
180
- assert response .status_code == 302
181
- response = self .client .options ('/redirect-view/' , follow = True )
182
- assert response .redirect_chain is not None
183
- assert response .status_code == 200
158
+ for method in ('get' , 'post' , 'put' , 'patch' , 'delete' , 'options' ):
159
+ with self .subTest (method = method ):
160
+ req_method = getattr (self .client , method )
161
+ response = req_method ('/redirect-view/' )
162
+ assert response .status_code == 302
163
+ response = req_method ('/redirect-view/' , follow = True )
164
+ assert response .redirect_chain is not None
165
+ assert response .status_code == 200
166
+
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
184
185
185
def test_invalid_multipart_data (self ):
186
186
"""
0 commit comments