Fixed #18924 -- Made test.Client.logout send user_logged_out signal.
Thanks awsum for the suggestion and Pavel Ponomarev and Florian Hahn for the patch.
This commit is contained in:
parent
e71b63e280
commit
a35ed20241
|
@ -13,7 +13,7 @@ except ImportError: # Python 2
|
||||||
from urlparse import urlparse, urlsplit
|
from urlparse import urlparse, urlsplit
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.auth import authenticate, login
|
from django.contrib.auth import authenticate, login, logout, get_user_model
|
||||||
from django.core.handlers.base import BaseHandler
|
from django.core.handlers.base import BaseHandler
|
||||||
from django.core.handlers.wsgi import WSGIRequest
|
from django.core.handlers.wsgi import WSGIRequest
|
||||||
from django.core.signals import (request_started, request_finished,
|
from django.core.signals import (request_started, request_finished,
|
||||||
|
@ -571,11 +571,17 @@ class Client(RequestFactory):
|
||||||
|
|
||||||
Causes the authenticated user to be logged out.
|
Causes the authenticated user to be logged out.
|
||||||
"""
|
"""
|
||||||
session = import_module(settings.SESSION_ENGINE).SessionStore()
|
request = HttpRequest()
|
||||||
session_cookie = self.cookies.get(settings.SESSION_COOKIE_NAME)
|
engine = import_module(settings.SESSION_ENGINE)
|
||||||
if session_cookie:
|
UserModel = get_user_model()
|
||||||
session.delete(session_key=session_cookie.value)
|
if self.session:
|
||||||
self.cookies = SimpleCookie()
|
request.session = self.session
|
||||||
|
uid = self.session.get("_auth_user_id")
|
||||||
|
if uid:
|
||||||
|
request.user = UserModel._default_manager.get(pk=uid)
|
||||||
|
else:
|
||||||
|
request.session = engine.SessionStore()
|
||||||
|
logout(request)
|
||||||
|
|
||||||
def _handle_redirects(self, response, **extra):
|
def _handle_redirects(self, response, **extra):
|
||||||
"Follows any redirects by requesting responses from the server using GET."
|
"Follows any redirects by requesting responses from the server using GET."
|
||||||
|
|
|
@ -623,6 +623,10 @@ Miscellaneous
|
||||||
raises NoReverseMatch. There is no change to {% url %} tag, it causes
|
raises NoReverseMatch. There is no change to {% url %} tag, it causes
|
||||||
template rendering to fail like always when NoReverseMatch is risen.
|
template rendering to fail like always when NoReverseMatch is risen.
|
||||||
|
|
||||||
|
* :meth:`django.test.client.Client.logout` now calls
|
||||||
|
:meth:`django.contrib.auth.logout` which will send the
|
||||||
|
:func:`~django.contrib.auth.signals.user_logged_out` signal.
|
||||||
|
|
||||||
Features deprecated in 1.6
|
Features deprecated in 1.6
|
||||||
==========================
|
==========================
|
||||||
|
|
||||||
|
|
|
@ -696,7 +696,7 @@ Use the ``django.test.client.Client`` class to make requests.
|
||||||
|
|
||||||
After you call this method, the test client will have all the cookies
|
After you call this method, the test client will have all the cookies
|
||||||
and session data cleared to defaults. Subsequent requests will appear
|
and session data cleared to defaults. Subsequent requests will appear
|
||||||
to come from an AnonymousUser.
|
to come from an :class:`~django.contrib.auth.models.AnonymousUser`.
|
||||||
|
|
||||||
Testing responses
|
Testing responses
|
||||||
~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
from django.db import models
|
||||||
|
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
|
||||||
|
|
||||||
|
|
||||||
|
class CustomUser(AbstractBaseUser):
|
||||||
|
email = models.EmailField(verbose_name='email address', max_length=255, unique=True)
|
||||||
|
custom_objects = BaseUserManager()
|
||||||
|
|
||||||
|
USERNAME_FIELD = 'email'
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
app_label = 'test_client_regress'
|
|
@ -17,7 +17,10 @@ from django.template.response import SimpleTemplateResponse
|
||||||
from django.utils._os import upath
|
from django.utils._os import upath
|
||||||
from django.utils.translation import ugettext_lazy
|
from django.utils.translation import ugettext_lazy
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse
|
||||||
|
from django.contrib.auth.signals import user_logged_out, user_logged_in
|
||||||
|
from django.contrib.auth.models import User
|
||||||
|
|
||||||
|
from .models import CustomUser
|
||||||
from .views import CustomTestException
|
from .views import CustomTestException
|
||||||
|
|
||||||
@override_settings(
|
@override_settings(
|
||||||
|
@ -961,6 +964,76 @@ class SessionTests(TestCase):
|
||||||
self.client.logout()
|
self.client.logout()
|
||||||
self.client.logout()
|
self.client.logout()
|
||||||
|
|
||||||
|
def test_logout_with_user(self):
|
||||||
|
"""Logout should send user_logged_out signal if user was logged in."""
|
||||||
|
def listener(*args, **kwargs):
|
||||||
|
listener.executed = True
|
||||||
|
self.assertEqual(kwargs['sender'], User)
|
||||||
|
listener.executed = False
|
||||||
|
|
||||||
|
user_logged_out.connect(listener)
|
||||||
|
self.client.login(username='testclient', password='password')
|
||||||
|
self.client.logout()
|
||||||
|
user_logged_out.disconnect(listener)
|
||||||
|
self.assertTrue(listener.executed)
|
||||||
|
|
||||||
|
@override_settings(AUTH_USER_MODEL='test_client_regress.CustomUser')
|
||||||
|
def test_logout_with_custom_user(self):
|
||||||
|
"""Logout should send user_logged_out signal if custom user was logged in."""
|
||||||
|
def listener(*args, **kwargs):
|
||||||
|
self.assertEqual(kwargs['sender'], CustomUser)
|
||||||
|
listener.executed = True
|
||||||
|
listener.executed = False
|
||||||
|
u = CustomUser.custom_objects.create(email='test@test.com')
|
||||||
|
u.set_password('password')
|
||||||
|
u.save()
|
||||||
|
|
||||||
|
user_logged_out.connect(listener)
|
||||||
|
self.client.login(username='test@test.com', password='password')
|
||||||
|
self.client.logout()
|
||||||
|
user_logged_out.disconnect(listener)
|
||||||
|
self.assertTrue(listener.executed)
|
||||||
|
|
||||||
|
def test_logout_without_user(self):
|
||||||
|
"""Logout should send signal even if user not authenticated."""
|
||||||
|
def listener(user, *args, **kwargs):
|
||||||
|
listener.user = user
|
||||||
|
listener.executed = True
|
||||||
|
listener.executed = False
|
||||||
|
|
||||||
|
user_logged_out.connect(listener)
|
||||||
|
self.client.login(username='incorrect', password='password')
|
||||||
|
self.client.logout()
|
||||||
|
user_logged_out.disconnect(listener)
|
||||||
|
|
||||||
|
self.assertTrue(listener.executed)
|
||||||
|
self.assertIsNone(listener.user)
|
||||||
|
|
||||||
|
def test_login_with_user(self):
|
||||||
|
"""Login should send user_logged_in signal on successful login."""
|
||||||
|
def listener(*args, **kwargs):
|
||||||
|
listener.executed = True
|
||||||
|
listener.executed = False
|
||||||
|
|
||||||
|
user_logged_in.connect(listener)
|
||||||
|
self.client.login(username='testclient', password='password')
|
||||||
|
user_logged_out.disconnect(listener)
|
||||||
|
|
||||||
|
self.assertTrue(listener.executed)
|
||||||
|
|
||||||
|
def test_login_without_signal(self):
|
||||||
|
"""Login shouldn't send signal if user wasn't logged in"""
|
||||||
|
def listener(*args, **kwargs):
|
||||||
|
listener.executed = True
|
||||||
|
listener.executed = False
|
||||||
|
|
||||||
|
user_logged_in.connect(listener)
|
||||||
|
self.client.login(username='incorrect', password='password')
|
||||||
|
user_logged_in.disconnect(listener)
|
||||||
|
|
||||||
|
self.assertFalse(listener.executed)
|
||||||
|
|
||||||
|
|
||||||
class RequestMethodTests(TestCase):
|
class RequestMethodTests(TestCase):
|
||||||
def test_get(self):
|
def test_get(self):
|
||||||
"Request a view via request method GET"
|
"Request a view via request method GET"
|
||||||
|
|
Loading…
Reference in New Issue