summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorRussell Keith-Magee <russell@keith-magee.com>2009-02-27 13:14:59 +0000
committerRussell Keith-Magee <russell@keith-magee.com>2009-02-27 13:14:59 +0000
commite735fe7160d786efeb2e8bea595174c1a68409a2 (patch)
tree006d378625943718f66d6c3791c7401a345378ce /tests
parente20f09c2d047d782b4b471b2e8cf4a910b338db6 (diff)
Fixed #4476 -- Added a ``follow`` option to the test client request methods. This implements browser-like behavior for the test client, following redirect chains when a 30X response is received. Thanks to Marc Fargas and Keith Bussell for their work on this.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@9911 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'tests')
-rw-r--r--tests/modeltests/test_client/models.py12
-rw-r--r--tests/regressiontests/test_client_regress/models.py101
-rw-r--r--tests/regressiontests/test_client_regress/urls.py10
-rw-r--r--tests/regressiontests/test_client_regress/views.py2
4 files changed, 121 insertions, 4 deletions
diff --git a/tests/modeltests/test_client/models.py b/tests/modeltests/test_client/models.py
index b975d139c6..dfc84169f3 100644
--- a/tests/modeltests/test_client/models.py
+++ b/tests/modeltests/test_client/models.py
@@ -70,13 +70,13 @@ class ClientTest(TestCase):
self.assertEqual(response.context['data'], '37')
self.assertEqual(response.template.name, 'POST Template')
self.failUnless('Data received' in response.content)
-
+
def test_response_headers(self):
"Check the value of HTTP headers returned in a response"
response = self.client.get("/test_client/header_view/")
-
+
self.assertEquals(response['X-DJANGO-TEST'], 'Slartibartfast')
-
+
def test_raw_post(self):
"POST raw data (with a content type) to a view"
test_doc = """<?xml version="1.0" encoding="utf-8"?><library><book><title>Blink</title><author>Malcolm Gladwell</author></book></library>"""
@@ -132,6 +132,12 @@ class ClientTest(TestCase):
# the attempt to get the redirection location returned 301 when retrieved
self.assertRedirects(response, 'http://testserver/test_client/permanent_redirect_view/', target_status_code=301)
+ def test_follow_redirect(self):
+ "A URL that redirects can be followed to termination."
+ response = self.client.get('/test_client/double_redirect_view/', follow=True)
+ self.assertRedirects(response, 'http://testserver/test_client/get_view/', status_code=302, target_status_code=200)
+ self.assertEquals(len(response.redirect_chain), 2)
+
def test_notfound_response(self):
"GET a URL that responds as '404:Not Found'"
response = self.client.get('/test_client/bad_view/')
diff --git a/tests/regressiontests/test_client_regress/models.py b/tests/regressiontests/test_client_regress/models.py
index 7015f71e00..16c26365dd 100644
--- a/tests/regressiontests/test_client_regress/models.py
+++ b/tests/regressiontests/test_client_regress/models.py
@@ -148,6 +148,107 @@ class AssertRedirectsTests(TestCase):
except AssertionError, e:
self.assertEquals(str(e), "Couldn't retrieve redirection page '/test_client/permanent_redirect_view/': response code was 301 (expected 200)")
+ def test_redirect_chain(self):
+ "You can follow a redirect chain of multiple redirects"
+ response = self.client.get('/test_client_regress/redirects/further/more/', {}, follow=True)
+ self.assertRedirects(response, '/test_client_regress/no_template_view/',
+ status_code=301, target_status_code=200)
+
+ self.assertEquals(len(response.redirect_chain), 1)
+ self.assertEquals(response.redirect_chain[0], ('http://testserver/test_client_regress/no_template_view/', 301))
+
+ def test_multiple_redirect_chain(self):
+ "You can follow a redirect chain of multiple redirects"
+ response = self.client.get('/test_client_regress/redirects/', {}, follow=True)
+ self.assertRedirects(response, '/test_client_regress/no_template_view/',
+ status_code=301, target_status_code=200)
+
+ self.assertEquals(len(response.redirect_chain), 3)
+ self.assertEquals(response.redirect_chain[0], ('http://testserver/test_client_regress/redirects/further/', 301))
+ self.assertEquals(response.redirect_chain[1], ('http://testserver/test_client_regress/redirects/further/more/', 301))
+ self.assertEquals(response.redirect_chain[2], ('http://testserver/test_client_regress/no_template_view/', 301))
+
+ def test_redirect_chain_to_non_existent(self):
+ "You can follow a chain to a non-existent view"
+ response = self.client.get('/test_client_regress/redirect_to_non_existent_view2/', {}, follow=True)
+ self.assertRedirects(response, '/test_client_regress/non_existent_view/',
+ status_code=301, target_status_code=404)
+
+ def test_redirect_chain_to_self(self):
+ "Redirections to self are caught and escaped"
+ response = self.client.get('/test_client_regress/redirect_to_self/', {}, follow=True)
+ # The chain of redirects stops once the cycle is detected.
+ self.assertRedirects(response, '/test_client_regress/redirect_to_self/',
+ status_code=301, target_status_code=301)
+ self.assertEquals(len(response.redirect_chain), 2)
+
+ def test_circular_redirect(self):
+ "Circular redirect chains are caught and escaped"
+ response = self.client.get('/test_client_regress/circular_redirect_1/', {}, follow=True)
+ # The chain of redirects will get back to the starting point, but stop there.
+ self.assertRedirects(response, '/test_client_regress/circular_redirect_2/',
+ status_code=301, target_status_code=301)
+ self.assertEquals(len(response.redirect_chain), 4)
+
+ def test_redirect_chain_post(self):
+ "A redirect chain will be followed from an initial POST post"
+ response = self.client.post('/test_client_regress/redirects/',
+ {'nothing': 'to_send'}, follow=True)
+ self.assertRedirects(response,
+ '/test_client_regress/no_template_view/', 301, 200)
+ self.assertEquals(len(response.redirect_chain), 3)
+
+ def test_redirect_chain_head(self):
+ "A redirect chain will be followed from an initial HEAD request"
+ response = self.client.head('/test_client_regress/redirects/',
+ {'nothing': 'to_send'}, follow=True)
+ self.assertRedirects(response,
+ '/test_client_regress/no_template_view/', 301, 200)
+ self.assertEquals(len(response.redirect_chain), 3)
+
+ def test_redirect_chain_options(self):
+ "A redirect chain will be followed from an initial OPTIONS request"
+ response = self.client.options('/test_client_regress/redirects/',
+ {'nothing': 'to_send'}, follow=True)
+ self.assertRedirects(response,
+ '/test_client_regress/no_template_view/', 301, 200)
+ self.assertEquals(len(response.redirect_chain), 3)
+
+ def test_redirect_chain_put(self):
+ "A redirect chain will be followed from an initial PUT request"
+ response = self.client.put('/test_client_regress/redirects/',
+ {'nothing': 'to_send'}, follow=True)
+ self.assertRedirects(response,
+ '/test_client_regress/no_template_view/', 301, 200)
+ self.assertEquals(len(response.redirect_chain), 3)
+
+ def test_redirect_chain_delete(self):
+ "A redirect chain will be followed from an initial DELETE request"
+ response = self.client.delete('/test_client_regress/redirects/',
+ {'nothing': 'to_send'}, follow=True)
+ self.assertRedirects(response,
+ '/test_client_regress/no_template_view/', 301, 200)
+ self.assertEquals(len(response.redirect_chain), 3)
+
+ def test_redirect_chain_on_non_redirect_page(self):
+ "An assertion is raised if the original page couldn't be retrieved as expected"
+ # This page will redirect with code 301, not 302
+ response = self.client.get('/test_client/get_view/', follow=True)
+ try:
+ self.assertRedirects(response, '/test_client/get_view/')
+ except AssertionError, e:
+ self.assertEquals(str(e), "Response didn't redirect as expected: Response code was 200 (expected 302)")
+
+ def test_redirect_on_non_redirect_page(self):
+ "An assertion is raised if the original page couldn't be retrieved as expected"
+ # This page will redirect with code 301, not 302
+ response = self.client.get('/test_client/get_view/')
+ try:
+ self.assertRedirects(response, '/test_client/get_view/')
+ except AssertionError, e:
+ self.assertEquals(str(e), "Response didn't redirect as expected: Response code was 200 (expected 302)")
+
+
class AssertFormErrorTests(TestCase):
def test_unknown_form(self):
"An assertion is raised if the form name is unknown"
diff --git a/tests/regressiontests/test_client_regress/urls.py b/tests/regressiontests/test_client_regress/urls.py
index e7db15a46b..9e573f6384 100644
--- a/tests/regressiontests/test_client_regress/urls.py
+++ b/tests/regressiontests/test_client_regress/urls.py
@@ -1,4 +1,5 @@
from django.conf.urls.defaults import *
+from django.views.generic.simple import redirect_to
import views
urlpatterns = patterns('',
@@ -8,6 +9,15 @@ urlpatterns = patterns('',
(r'^request_data/$', views.request_data),
url(r'^arg_view/(?P<name>.+)/$', views.view_with_argument, name='arg_view'),
(r'^login_protected_redirect_view/$', views.login_protected_redirect_view),
+ (r'^redirects/$', redirect_to, {'url': '/test_client_regress/redirects/further/'}),
+ (r'^redirects/further/$', redirect_to, {'url': '/test_client_regress/redirects/further/more/'}),
+ (r'^redirects/further/more/$', redirect_to, {'url': '/test_client_regress/no_template_view/'}),
+ (r'^redirect_to_non_existent_view/$', redirect_to, {'url': '/test_client_regress/non_existent_view/'}),
+ (r'^redirect_to_non_existent_view2/$', redirect_to, {'url': '/test_client_regress/redirect_to_non_existent_view/'}),
+ (r'^redirect_to_self/$', redirect_to, {'url': '/test_client_regress/redirect_to_self/'}),
+ (r'^circular_redirect_1/$', redirect_to, {'url': '/test_client_regress/circular_redirect_2/'}),
+ (r'^circular_redirect_2/$', redirect_to, {'url': '/test_client_regress/circular_redirect_3/'}),
+ (r'^circular_redirect_3/$', redirect_to, {'url': '/test_client_regress/circular_redirect_1/'}),
(r'^set_session/$', views.set_session_view),
(r'^check_session/$', views.check_session_view),
(r'^request_methods/$', views.request_methods_view),
diff --git a/tests/regressiontests/test_client_regress/views.py b/tests/regressiontests/test_client_regress/views.py
index e62f6a17c5..453c37a32e 100644
--- a/tests/regressiontests/test_client_regress/views.py
+++ b/tests/regressiontests/test_client_regress/views.py
@@ -58,4 +58,4 @@ def check_session_view(request):
def request_methods_view(request):
"A view that responds with the request method"
- return HttpResponse('request method: %s' % request.method) \ No newline at end of file
+ return HttpResponse('request method: %s' % request.method)