Skip to content

Commit 2dfe75c

Browse files
committed
Fix follow does not work on APIClient
Handle follow just like Django's Client.
1 parent ad14978 commit 2dfe75c

File tree

2 files changed

+93
-0
lines changed

2 files changed

+93
-0
lines changed

rest_framework/test.py

+46
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,52 @@ def request(self, **kwargs):
156156
kwargs.update(self._credentials)
157157
return super(APIClient, self).request(**kwargs)
158158

159+
def get(self, path, data=None, follow=False, **extra):
160+
response = super(APIClient, self).get(path, data=data, **extra)
161+
if follow:
162+
response = self._handle_redirects(response, **extra)
163+
return response
164+
165+
def post(self, path, data=None, format=None, content_type=None,
166+
follow=False, **extra):
167+
response = super(APIClient, self).post(
168+
path, data=data, format=format, content_type=content_type, **extra)
169+
if follow:
170+
response = self._handle_redirects(response, **extra)
171+
return response
172+
173+
def put(self, path, data=None, format=None, content_type=None,
174+
follow=False, **extra):
175+
response = super(APIClient, self).put(
176+
path, data=data, format=format, content_type=content_type, **extra)
177+
if follow:
178+
response = self._handle_redirects(response, **extra)
179+
return response
180+
181+
def patch(self, path, data=None, format=None, content_type=None,
182+
follow=False, **extra):
183+
response = super(APIClient, self).patch(
184+
path, data=data, format=format, content_type=content_type, **extra)
185+
if follow:
186+
response = self._handle_redirects(response, **extra)
187+
return response
188+
189+
def delete(self, path, data=None, format=None, content_type=None,
190+
follow=False, **extra):
191+
response = super(APIClient, self).delete(
192+
path, data=data, format=format, content_type=content_type, **extra)
193+
if follow:
194+
response = self._handle_redirects(response, **extra)
195+
return response
196+
197+
def options(self, path, data=None, format=None, content_type=None,
198+
follow=False, **extra):
199+
response = super(APIClient, self).options(
200+
path, data=data, format=format, content_type=content_type, **extra)
201+
if follow:
202+
response = self._handle_redirects(response, **extra)
203+
return response
204+
159205
def logout(self):
160206
self._credentials = {}
161207
return super(APIClient, self).logout()

tests/test_testing.py

+47
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from io import BytesIO
66

77
from django.contrib.auth.models import User
8+
from django.shortcuts import redirect
89
from django.test import TestCase
910
from rest_framework.decorators import api_view
1011
from rest_framework.response import Response
@@ -28,10 +29,16 @@ def session_view(request):
2829
})
2930

3031

32+
@api_view(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'])
33+
def redirect_view(request):
34+
return redirect('/view/')
35+
36+
3137
urlpatterns = patterns(
3238
'',
3339
url(r'^view/$', view),
3440
url(r'^session-view/$', session_view),
41+
url(r'^redirect-view/$', redirect_view),
3542
)
3643

3744

@@ -111,6 +118,46 @@ def test_can_logout(self):
111118
response = self.client.get('/view/')
112119
self.assertEqual(response.data['auth'], b'')
113120

121+
def test_follow_redirect(self):
122+
"""
123+
Follow redirect by setting follow argument.
124+
"""
125+
response = self.client.get('/redirect-view/')
126+
self.assertEqual(response.status_code, 302)
127+
response = self.client.get('/redirect-view/', follow=True)
128+
self.assertIsNotNone(response.redirect_chain)
129+
self.assertEqual(response.status_code, 200)
130+
131+
response = self.client.post('/redirect-view/')
132+
self.assertEqual(response.status_code, 302)
133+
response = self.client.post('/redirect-view/', follow=True)
134+
self.assertIsNotNone(response.redirect_chain)
135+
self.assertEqual(response.status_code, 200)
136+
137+
response = self.client.put('/redirect-view/')
138+
self.assertEqual(response.status_code, 302)
139+
response = self.client.put('/redirect-view/', follow=True)
140+
self.assertIsNotNone(response.redirect_chain)
141+
self.assertEqual(response.status_code, 200)
142+
143+
response = self.client.patch('/redirect-view/')
144+
self.assertEqual(response.status_code, 302)
145+
response = self.client.patch('/redirect-view/', follow=True)
146+
self.assertIsNotNone(response.redirect_chain)
147+
self.assertEqual(response.status_code, 200)
148+
149+
response = self.client.delete('/redirect-view/')
150+
self.assertEqual(response.status_code, 302)
151+
response = self.client.delete('/redirect-view/', follow=True)
152+
self.assertIsNotNone(response.redirect_chain)
153+
self.assertEqual(response.status_code, 200)
154+
155+
response = self.client.options('/redirect-view/')
156+
self.assertEqual(response.status_code, 302)
157+
response = self.client.options('/redirect-view/', follow=True)
158+
self.assertIsNotNone(response.redirect_chain)
159+
self.assertEqual(response.status_code, 200)
160+
114161

115162
class TestAPIRequestFactory(TestCase):
116163
def test_csrf_exempt_by_default(self):

0 commit comments

Comments
 (0)