Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed #20916 - Added support for a simple_login test client method. #2570

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions django/contrib/auth/backends.py
Expand Up @@ -134,3 +134,8 @@ def configure_user(self, user):
By default, returns the user unmodified.
"""
return user


class SimpleLoginBackend(ModelBackend):
def authenticate(self, user):
return user
4 changes: 2 additions & 2 deletions django/contrib/auth/checks.py
Expand Up @@ -4,6 +4,7 @@
from django.apps import apps
from django.conf import settings
from django.core import checks
from django.test.utils import TEST_ENVIRON_AUTHENTICATION_BACKENDS


def check_user_model(**kwargs):
Expand Down Expand Up @@ -36,8 +37,7 @@ def check_user_model(**kwargs):

# Check that the username field is unique
if not cls._meta.get_field(cls.USERNAME_FIELD).unique:
if (settings.AUTHENTICATION_BACKENDS ==
('django.contrib.auth.backends.ModelBackend',)):
if (settings.AUTHENTICATION_BACKENDS == TEST_ENVIRON_AUTHENTICATION_BACKENDS):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change isn't correct as it will disable the check unless testing. Maybe this would work: if 'django.contrib.auth.backends.ModelBackend' in settings.AUTHENTICATION_BACKENDS

errors.append(
checks.Error(
"'%s.%s' must be unique because it is named as the 'USERNAME_FIELD'." % (
Expand Down
12 changes: 12 additions & 0 deletions django/contrib/auth/tests/test_auth_backends.py
Expand Up @@ -531,3 +531,15 @@ def test_does_not_shadow_exception(self):
request.session = self.client.session

self.assertRaises(ImproperlyConfigured, get_user, request)


@skipIfCustomUser
class SimpleLoginBackendTest(TestCase):
def test_authenticate(self):
test_user = CustomUser._default_manager.create_user(
email='test@example.com',
password='test',
date_of_birth=date(2006, 4, 25)
)
authenticated_user = authenticate(user=test_user)
self.assertEqual(test_user, authenticated_user)
3 changes: 3 additions & 0 deletions django/test/client.py
Expand Up @@ -581,6 +581,9 @@ def login(self, **credentials):
else:
return False

def simple_login(self, user):
return self.login(user=user)

def logout(self):
"""
Removes the authenticated user's cookies and session object.
Expand Down
8 changes: 8 additions & 0 deletions django/test/utils.py
Expand Up @@ -10,6 +10,7 @@

from django.apps import apps
from django.conf import settings, UserSettingsHolder
from django.contrib import auth
from django.core import mail
from django.core.signals import request_started
from django.db import reset_queries
Expand All @@ -32,6 +33,7 @@

RESTORE_LOADERS_ATTR = '_original_template_source_loaders'
TZ_SUPPORT = hasattr(time, 'tzset')
TEST_ENVIRON_AUTHENTICATION_BACKENDS = settings.AUTHENTICATION_BACKENDS + ('django.contrib.auth.backends.SimpleLoginBackend',)


class Approximate(object):
Expand Down Expand Up @@ -107,6 +109,9 @@ def setup_test_environment():
request._original_allowed_hosts = settings.ALLOWED_HOSTS
settings.ALLOWED_HOSTS = ['*']

auth._original_authentication_backends = settings.AUTHENTICATION_BACKENDS
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this patching happen in the simple_login() method? Otherwise, login() is affected as well which means it wouldn't reject invalid credentials Am I missing something?

settings.AUTHENTICATION_BACKENDS = TEST_ENVIRON_AUTHENTICATION_BACKENDS

mail.outbox = []

deactivate()
Expand All @@ -128,6 +133,9 @@ def teardown_test_environment():
settings.ALLOWED_HOSTS = request._original_allowed_hosts
del request._original_allowed_hosts

settings.AUTHENTICATION_BACKENDS = auth._original_authentication_backends
del auth._original_authentication_backends

del mail.outbox


Expand Down
26 changes: 26 additions & 0 deletions tests/test_client/tests.py
Expand Up @@ -22,6 +22,7 @@
"""
from __future__ import unicode_literals

from django.contrib.auth.models import User
from django.core import mail
from django.test import Client, TestCase, RequestFactory
from django.test import override_settings
Expand Down Expand Up @@ -366,6 +367,31 @@ def test_view_with_inactive_login(self):
login = self.client.login(username='inactive', password='password')
self.assertFalse(login)

def test_simple_login_with_active_user_logs_in_successfully(self):
user = User.objects.filter(is_active=True)[0]
self.assertIsNotNone(user, 'Test precondition failed. Could not find an active User instance.')

# Log in
login = self.client.simple_login(user)
self.assertTrue(login)

# Request a page that requires a logged in user
response = self.client.get('/login_protected_method_view/')
self.assertEqual(response.status_code, 200)
self.assertEqual(response.context['user'].username, user.username)

def test_simple_login_with_inactive_user_gets_redirected_to_login_page(self):
user = User.objects.filter(is_active=False)[0]
self.assertIsNotNone(user, 'Test precondition failed. Could not find an inactive User instance.')

# Log in with inactive user
login = self.client.simple_login(user)
self.assertFalse(login)

# Request a page that requires a logged in user
response = self.client.get('/login_protected_method_view/')
self.assertRedirects(response, 'http://testserver/accounts/login/?next=/login_protected_method_view/')

def test_logout(self):
"Request a logout after logging in"
# Log in
Expand Down