diff options
| author | Russell Keith-Magee <russell@keith-magee.com> | 2009-02-27 13:14:59 +0000 |
|---|---|---|
| committer | Russell Keith-Magee <russell@keith-magee.com> | 2009-02-27 13:14:59 +0000 |
| commit | e735fe7160d786efeb2e8bea595174c1a68409a2 (patch) | |
| tree | 006d378625943718f66d6c3791c7401a345378ce /tests | |
| parent | e20f09c2d047d782b4b471b2e8cf4a910b338db6 (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.py | 12 | ||||
| -rw-r--r-- | tests/regressiontests/test_client_regress/models.py | 101 | ||||
| -rw-r--r-- | tests/regressiontests/test_client_regress/urls.py | 10 | ||||
| -rw-r--r-- | tests/regressiontests/test_client_regress/views.py | 2 |
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) |
