diff --git a/AUTHORS b/AUTHORS index c690980c90..a0032f5198 100644 --- a/AUTHORS +++ b/AUTHORS @@ -284,6 +284,7 @@ answer newbie questions, and generally made Django that much better: charly.wilhelm@gmail.com Rachel Willmer Gary Wilson + Jakub Wiśniowski wojtek ye7cakf02@sneakemail.com ymasuda@ethercube.com diff --git a/django/test/client.py b/django/test/client.py index 7e62715205..9ec3615973 100644 --- a/django/test/client.py +++ b/django/test/client.py @@ -253,3 +253,14 @@ class Client: else: return False + def logout(self): + """Removes the authenticated user's cookies. + + Causes the authenticated user to be logged out. + """ + try: + Session.objects.get(session_key=self.cookies['sessionid'].value).delete() + except KeyError: + pass + + self.cookies = SimpleCookie() diff --git a/docs/testing.txt b/docs/testing.txt index 4e723a1020..f189aa4578 100644 --- a/docs/testing.txt +++ b/docs/testing.txt @@ -550,6 +550,17 @@ Once you have a ``Client`` instance, you can call any of the following methods: conditions. You'll need to create users as part of the test suite -- either manually (using the Django model API) or with a test fixture. +``logout()`` + **New in Django development version** + + If your site uses Django's `authentication system`_, the ``logout()`` + method can be used to simulate the effect of a user logging out of + your site. + + After you call this method, the test client will have all the cookies and + session data cleared to defaults. Subsequent requests will appear to + come from an AnonymousUser. + .. _authentication system: ../authentication/ .. _authentication backend: ../authentication/#other-authentication-sources @@ -758,7 +769,7 @@ Here's specifically what will happen: * At the start of each test case, before ``setUp()`` is run, Django will flush the database, returning the database to the state it was in directly after ``syncdb`` was called. - + * Then, all the named fixtures are installed. In this example, Django will install any JSON fixture named ``mammals``, followed by any fixture named ``birds``. See the `loaddata documentation`_ for more details on defining @@ -843,7 +854,7 @@ The test runner accomplishes this by transparently replacing the normal effect on any other e-mail senders outside of Django, such as your machine's mail server, if you're running one.) -During test running, each outgoing e-mail is saved in +During test running, each outgoing e-mail is saved in ``django.core.mail.outbox``. This is a simple list of all `EmailMessage`_ instances that have been sent. It does not exist under normal execution conditions, i.e., when you're not running unit tests. The outbox is created @@ -977,7 +988,7 @@ a number of utility methods in the ``django.test.utils`` module. ``autoclobber`` describes the behavior that will occur if a database with the same name as the test database is discovered: - + * If ``autoclobber`` is ``False``, the user will be asked to approve destroying the existing database. ``sys.exit`` is called if the user does not approve. diff --git a/tests/modeltests/test_client/models.py b/tests/modeltests/test_client/models.py index 951a41d61c..98b6a808a1 100644 --- a/tests/modeltests/test_client/models.py +++ b/tests/modeltests/test_client/models.py @@ -246,6 +246,22 @@ class ClientTest(TestCase): login = self.client.login(username='inactive', password='password') self.failIf(login) + def test_logout(self): + # Log in + self.client.login(username='testclient', password='password') + + # Request a page that requires a login + response = self.client.get('/test_client/login_protected_view/') + self.assertEqual(response.status_code, 200) + self.assertEqual(response.context['user'].username, 'testclient') + + # Log out + self.client.logout() + + # Request a page that requires a login + response = self.client.get('/test_client/login_protected_view/') + self.assertRedirects(response, '/accounts/login/') + def test_session_modifying_view(self): "Request a page that modifies the session" # Session value isn't set initially