diff --git a/AUTHORS b/AUTHORS index c57cc23a5d0..8fa87d07bc7 100644 --- a/AUTHORS +++ b/AUTHORS @@ -367,6 +367,7 @@ answer newbie questions, and generally made Django that much better: George Vilches Vlado Milton Waddams + Chris Wagner wam-djangobug@wamber.net Wang Chun Filip Wasilewski diff --git a/django/test/client.py b/django/test/client.py index bf9d85120e9..a15876e6f9c 100644 --- a/django/test/client.py +++ b/django/test/client.py @@ -179,10 +179,15 @@ class Client: if e.args != ('500.html',): raise - # Look for a signalled exception and reraise it + # Look for a signalled exception, clear the current context + # exception data, then re-raise the signalled exception. + # Also make sure that the signalled exception is cleared from + # the local cache! if self.exc_info: - raise self.exc_info[1], None, self.exc_info[2] - + exc_info = self.exc_info + self.exc_info = None + raise exc_info[1], None, exc_info[2] + # Save the client and request that stimulated the response response.client = self response.request = request diff --git a/tests/modeltests/test_client/fixtures/testdata.json b/tests/modeltests/test_client/fixtures/testdata.json index e9d3ebe9a8f..0dcf6259392 100644 --- a/tests/modeltests/test_client/fixtures/testdata.json +++ b/tests/modeltests/test_client/fixtures/testdata.json @@ -34,5 +34,23 @@ "email": "testclient@example.com", "date_joined": "2006-12-17 07:03:31" } + }, + { + "pk": "3", + "model": "auth.user", + "fields": { + "username": "staff", + "first_name": "Staff", + "last_name": "Member", + "is_active": true, + "is_superuser": false, + "is_staff": true, + "last_login": "2006-12-17 07:03:31", + "groups": [], + "user_permissions": [], + "password": "sha1$6efc0$f93efe9fd7542f25a7be94871ea45aa95de57161", + "email": "testclient@example.com", + "date_joined": "2006-12-17 07:03:31" + } } ] \ No newline at end of file diff --git a/tests/regressiontests/test_client_regress/fixtures/testdata.json b/tests/regressiontests/test_client_regress/fixtures/testdata.json index 5c9e4152408..0dcf6259392 100644 --- a/tests/regressiontests/test_client_regress/fixtures/testdata.json +++ b/tests/regressiontests/test_client_regress/fixtures/testdata.json @@ -16,5 +16,41 @@ "email": "testclient@example.com", "date_joined": "2006-12-17 07:03:31" } + }, + { + "pk": "2", + "model": "auth.user", + "fields": { + "username": "inactive", + "first_name": "Inactive", + "last_name": "User", + "is_active": false, + "is_superuser": false, + "is_staff": false, + "last_login": "2006-12-17 07:03:31", + "groups": [], + "user_permissions": [], + "password": "sha1$6efc0$f93efe9fd7542f25a7be94871ea45aa95de57161", + "email": "testclient@example.com", + "date_joined": "2006-12-17 07:03:31" + } + }, + { + "pk": "3", + "model": "auth.user", + "fields": { + "username": "staff", + "first_name": "Staff", + "last_name": "Member", + "is_active": true, + "is_superuser": false, + "is_staff": true, + "last_login": "2006-12-17 07:03:31", + "groups": [], + "user_permissions": [], + "password": "sha1$6efc0$f93efe9fd7542f25a7be94871ea45aa95de57161", + "email": "testclient@example.com", + "date_joined": "2006-12-17 07:03:31" + } } ] \ No newline at end of file diff --git a/tests/regressiontests/test_client_regress/models.py b/tests/regressiontests/test_client_regress/models.py index 8a1ed27a1d7..a204ec3e72e 100644 --- a/tests/regressiontests/test_client_regress/models.py +++ b/tests/regressiontests/test_client_regress/models.py @@ -4,6 +4,7 @@ Regression tests for the Test Client, especially the customized assertions. """ from django.test import Client, TestCase from django.core.urlresolvers import reverse +from django.core.exceptions import SuspiciousOperation import os class AssertContainsTests(TestCase): @@ -294,4 +295,26 @@ class URLEscapingTests(TestCase): self.assertEqual(response.status_code, 200) self.assertEqual(response.content, 'Hi, Arthur') +class ExceptionTests(TestCase): + fixtures = ['testdata.json'] + + def test_exception_cleared(self): + "#5836 - A stale user exception isn't re-raised by the test client." + login = self.client.login(username='testclient',password='password') + self.failUnless(login, 'Could not log in') + try: + response = self.client.get("/test_client_regress/staff_only/") + self.fail("General users should not be able to visit this page") + except SuspiciousOperation: + pass + + # At this point, an exception has been raised, and should be cleared. + + # This next operation should be successful; if it isn't we have a problem. + login = self.client.login(username='staff', password='password') + self.failUnless(login, 'Could not log in') + try: + self.client.get("/test_client_regress/staff_only/") + except SuspiciousOperation: + self.fail("Staff should be able to visit this page") diff --git a/tests/regressiontests/test_client_regress/urls.py b/tests/regressiontests/test_client_regress/urls.py index d3304caef0e..dc26d1260ab 100644 --- a/tests/regressiontests/test_client_regress/urls.py +++ b/tests/regressiontests/test_client_regress/urls.py @@ -4,6 +4,7 @@ import views urlpatterns = patterns('', (r'^no_template_view/$', views.no_template_view), (r'^file_upload/$', views.file_upload_view), + (r'^staff_only/$', views.staff_only_view), (r'^get_view/$', views.get_view), url(r'^arg_view/(?P.+)/$', views.view_with_argument, name='arg_view'), (r'^login_protected_redirect_view/$', views.login_protected_redirect_view) diff --git a/tests/regressiontests/test_client_regress/views.py b/tests/regressiontests/test_client_regress/views.py index 97379c10394..9632c172847 100644 --- a/tests/regressiontests/test_client_regress/views.py +++ b/tests/regressiontests/test_client_regress/views.py @@ -2,6 +2,7 @@ import os from django.contrib.auth.decorators import login_required from django.http import HttpResponse, HttpResponseRedirect, HttpResponseServerError +from django.core.exceptions import SuspiciousOperation def no_template_view(request): "A simple view that expects a GET request, and returns a rendered template" @@ -23,6 +24,13 @@ def file_upload_view(request): else: return HttpResponseServerError() +def staff_only_view(request): + "A view that can only be visited by staff. Non staff members get an exception" + if request.user.is_staff: + return HttpResponse('') + else: + raise SuspiciousOperation() + def get_view(request): "A simple login protected view" return HttpResponse("Hello world")