test_signals.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. from django.apps import apps
  2. from django.contrib.auth import authenticate, signals
  3. from django.contrib.auth.models import User
  4. from django.core.exceptions import FieldDoesNotExist
  5. from django.test import TestCase, override_settings
  6. from django.test.client import RequestFactory
  7. from .models import MinimalUser, UserWithDisabledLastLoginField
  8. @override_settings(ROOT_URLCONF="auth_tests.urls")
  9. class SignalTestCase(TestCase):
  10. @classmethod
  11. def setUpTestData(cls):
  12. cls.u1 = User.objects.create_user(username="testclient", password="password")
  13. cls.u3 = User.objects.create_user(username="staff", password="password")
  14. def listener_login(self, user, **kwargs):
  15. self.logged_in.append(user)
  16. def listener_logout(self, user, **kwargs):
  17. self.logged_out.append(user)
  18. def listener_login_failed(self, sender, **kwargs):
  19. self.login_failed.append(kwargs)
  20. def setUp(self):
  21. """Set up the listeners and reset the logged in/logged out counters"""
  22. self.logged_in = []
  23. self.logged_out = []
  24. self.login_failed = []
  25. signals.user_logged_in.connect(self.listener_login)
  26. signals.user_logged_out.connect(self.listener_logout)
  27. signals.user_login_failed.connect(self.listener_login_failed)
  28. def tearDown(self):
  29. """Disconnect the listeners"""
  30. signals.user_logged_in.disconnect(self.listener_login)
  31. signals.user_logged_out.disconnect(self.listener_logout)
  32. signals.user_login_failed.disconnect(self.listener_login_failed)
  33. def test_login(self):
  34. # Only a successful login will trigger the success signal.
  35. self.client.login(username="testclient", password="bad")
  36. self.assertEqual(len(self.logged_in), 0)
  37. self.assertEqual(len(self.login_failed), 1)
  38. self.assertEqual(self.login_failed[0]["credentials"]["username"], "testclient")
  39. # verify the password is cleansed
  40. self.assertIn("***", self.login_failed[0]["credentials"]["password"])
  41. self.assertIn("request", self.login_failed[0])
  42. # Like this:
  43. self.client.login(username="testclient", password="password")
  44. self.assertEqual(len(self.logged_in), 1)
  45. self.assertEqual(self.logged_in[0].username, "testclient")
  46. # Ensure there were no more failures.
  47. self.assertEqual(len(self.login_failed), 1)
  48. def test_logout_anonymous(self):
  49. # The log_out function will still trigger the signal for anonymous
  50. # users.
  51. self.client.post("/logout/next_page/")
  52. self.assertEqual(len(self.logged_out), 1)
  53. self.assertIsNone(self.logged_out[0])
  54. def test_logout(self):
  55. self.client.login(username="testclient", password="password")
  56. self.client.post("/logout/next_page/")
  57. self.assertEqual(len(self.logged_out), 1)
  58. self.assertEqual(self.logged_out[0].username, "testclient")
  59. def test_update_last_login(self):
  60. """Only `last_login` is updated in `update_last_login`"""
  61. user = self.u3
  62. old_last_login = user.last_login
  63. user.username = "This username shouldn't get saved"
  64. request = RequestFactory().get("/login")
  65. signals.user_logged_in.send(sender=user.__class__, request=request, user=user)
  66. user = User.objects.get(pk=user.pk)
  67. self.assertEqual(user.username, "staff")
  68. self.assertNotEqual(user.last_login, old_last_login)
  69. def test_failed_login_without_request(self):
  70. authenticate(username="testclient", password="bad")
  71. self.assertIsNone(self.login_failed[0]["request"])
  72. def test_login_with_custom_user_without_last_login_field(self):
  73. """
  74. The user_logged_in signal is only registered if the user model has a
  75. last_login field.
  76. """
  77. last_login_receivers = signals.user_logged_in.receivers
  78. try:
  79. signals.user_logged_in.receivers = []
  80. with self.assertRaises(FieldDoesNotExist):
  81. MinimalUser._meta.get_field("last_login")
  82. with self.settings(AUTH_USER_MODEL="auth_tests.MinimalUser"):
  83. apps.get_app_config("auth").ready()
  84. self.assertEqual(signals.user_logged_in.receivers, [])
  85. # last_login is a property whose value is None.
  86. self.assertIsNone(UserWithDisabledLastLoginField().last_login)
  87. with self.settings(
  88. AUTH_USER_MODEL="auth_tests.UserWithDisabledLastLoginField"
  89. ):
  90. apps.get_app_config("auth").ready()
  91. self.assertEqual(signals.user_logged_in.receivers, [])
  92. with self.settings(AUTH_USER_MODEL="auth.User"):
  93. apps.get_app_config("auth").ready()
  94. self.assertEqual(len(signals.user_logged_in.receivers), 1)
  95. finally:
  96. signals.user_logged_in.receivers = last_login_receivers