diff --git a/django/contrib/auth/tests/__init__.py b/django/contrib/auth/tests/__init__.py index bd86111586..9a381ef93d 100644 --- a/django/contrib/auth/tests/__init__.py +++ b/django/contrib/auth/tests/__init__.py @@ -1,6 +1,6 @@ from django.contrib.auth.tests.basic import BASIC_TESTS from django.contrib.auth.tests.views \ - import PasswordResetTest, ChangePasswordTest, LoginTest + import PasswordResetTest, ChangePasswordTest, LoginTest, LogoutTest from django.contrib.auth.tests.forms import FORM_TESTS from django.contrib.auth.tests.remote_user \ import RemoteUserTest, RemoteUserNoCreateTest, RemoteUserCustomTest @@ -15,4 +15,5 @@ __test__ = { 'TOKEN_GENERATOR_TESTS': TOKEN_GENERATOR_TESTS, 'CHANGEPASSWORD_TESTS': ChangePasswordTest, 'LOGIN_TESTS': LoginTest, + 'LOGOUT_TESTS': LogoutTest, } diff --git a/django/contrib/auth/tests/urls.py b/django/contrib/auth/tests/urls.py new file mode 100644 index 0000000000..492d1c74f4 --- /dev/null +++ b/django/contrib/auth/tests/urls.py @@ -0,0 +1,9 @@ +from django.conf.urls.defaults import patterns +from django.contrib.auth.urls import urlpatterns + +# special urls for auth test cases +urlpatterns += patterns('', + (r'^logout/custom_query/$', 'django.contrib.auth.views.logout', dict(redirect_field_name='follow')), + (r'^logout/next_page/$', 'django.contrib.auth.views.logout', dict(next_page='/somewhere/')), +) + diff --git a/django/contrib/auth/tests/views.py b/django/contrib/auth/tests/views.py index 754241d5d2..f2faf09228 100644 --- a/django/contrib/auth/tests/views.py +++ b/django/contrib/auth/tests/views.py @@ -1,8 +1,8 @@ - import os import re from django.conf import settings +from django.contrib.auth import SESSION_KEY from django.contrib.auth.forms import AuthenticationForm from django.contrib.sites.models import Site, RequestSite from django.contrib.auth.models import User @@ -184,4 +184,52 @@ class LoginTest(TestCase): self.assertEquals(response.context['site_name'], site.name) self.assert_(isinstance(response.context['form'], AuthenticationForm), 'Login form is not an AuthenticationForm') - \ No newline at end of file + +class LogoutTest(TestCase): + fixtures = ['authtestdata.json'] + urls = 'django.contrib.auth.tests.urls' + + def login(self, password='password'): + response = self.client.post('/login/', { + 'username': 'testclient', + 'password': password + } + ) + self.assertEquals(response.status_code, 302) + self.assert_(response['Location'].endswith(settings.LOGIN_REDIRECT_URL)) + self.assert_(SESSION_KEY in self.client.session) + + def confirm_logged_out(self): + self.assert_(SESSION_KEY not in self.client.session) + + def test_logout_default(self): + "Logout without next_page option renders the default template" + self.login() + response = self.client.get('/logout/') + self.assertEquals(200, response.status_code) + self.assert_('Logged out' in response.content) + self.confirm_logged_out() + + def test_logout_with_next_page_specified(self): + "Logout with next_page option given redirects to specified resource" + self.login() + response = self.client.get('/logout/next_page/') + self.assertEqual(response.status_code, 302) + self.assert_(response['Location'].endswith('/somewhere/')) + self.confirm_logged_out() + + def test_logout_with_redirect_argument(self): + "Logout with query string redirects to specified resource" + self.login() + response = self.client.get('/logout/?next=/login/') + self.assertEqual(response.status_code, 302) + self.assert_(response['Location'].endswith('/login/')) + self.confirm_logged_out() + + def test_logout_with_custom_redirect_argument(self): + "Logout with custom query string redirects to specified resource" + self.login() + response = self.client.get('/logout/custom_query/?follow=/somewhere/') + self.assertEqual(response.status_code, 302) + self.assert_(response['Location'].endswith('/somewhere/')) + self.confirm_logged_out() \ No newline at end of file diff --git a/django/contrib/auth/views.py b/django/contrib/auth/views.py index 18572f1584..f753ed6de8 100644 --- a/django/contrib/auth/views.py +++ b/django/contrib/auth/views.py @@ -43,12 +43,18 @@ def login(request, template_name='registration/login.html', redirect_field_name= }, context_instance=RequestContext(request)) login = never_cache(login) -def logout(request, next_page=None, template_name='registration/logged_out.html'): +def logout(request, next_page=None, template_name='registration/logged_out.html', redirect_field_name=REDIRECT_FIELD_NAME): "Logs out the user and displays 'You are logged out' message." from django.contrib.auth import logout logout(request) if next_page is None: - return render_to_response(template_name, {'title': _('Logged out')}, context_instance=RequestContext(request)) + redirect_to = request.REQUEST.get(redirect_field_name, '') + if redirect_to: + return HttpResponseRedirect(redirect_to) + else: + return render_to_response(template_name, { + 'title': _('Logged out') + }, context_instance=RequestContext(request)) else: # Redirect to this page until the session has been cleared. return HttpResponseRedirect(next_page or request.path)