from __future__ import unicode_literals from django.contrib.auth.checks import check_user_model from django.contrib.auth.models import AbstractBaseUser from django.core import checks from django.db import models from django.test import ( SimpleTestCase, override_settings, override_system_checks, ) from django.test.utils import isolate_apps from .models import CustomUserNonUniqueUsername @isolate_apps('auth_tests', attr_name='apps') @override_system_checks([check_user_model]) class UserModelChecksTests(SimpleTestCase): @override_settings(AUTH_USER_MODEL='auth_tests.CustomUserNonListRequiredFields') def test_required_fields_is_list(self): """REQUIRED_FIELDS should be a list.""" class CustomUserNonListRequiredFields(AbstractBaseUser): username = models.CharField(max_length=30, unique=True) date_of_birth = models.DateField() USERNAME_FIELD = 'username' REQUIRED_FIELDS = 'date_of_birth' errors = checks.run_checks(app_configs=self.apps.get_app_configs()) self.assertEqual(errors, [ checks.Error( "'REQUIRED_FIELDS' must be a list or tuple.", obj=CustomUserNonListRequiredFields, id='auth.E001', ), ]) @override_settings(AUTH_USER_MODEL='auth_tests.CustomUserBadRequiredFields') def test_username_not_in_required_fields(self): """USERNAME_FIELD should not appear in REQUIRED_FIELDS.""" class CustomUserBadRequiredFields(AbstractBaseUser): username = models.CharField(max_length=30, unique=True) date_of_birth = models.DateField() USERNAME_FIELD = 'username' REQUIRED_FIELDS = ['username', 'date_of_birth'] errors = checks.run_checks(self.apps.get_app_configs()) self.assertEqual(errors, [ checks.Error( "The field named as the 'USERNAME_FIELD' for a custom user model " "must not be included in 'REQUIRED_FIELDS'.", obj=CustomUserBadRequiredFields, id='auth.E002', ), ]) @override_settings(AUTH_USER_MODEL='auth_tests.CustomUserNonUniqueUsername') def test_username_non_unique(self): """ A non-unique USERNAME_FIELD should raise an error only if we use the default authentication backend. Otherwise, an warning should be raised. """ errors = checks.run_checks() self.assertEqual(errors, [ checks.Error( "'CustomUserNonUniqueUsername.username' must be " "unique because it is named as the 'USERNAME_FIELD'.", obj=CustomUserNonUniqueUsername, id='auth.E003', ), ]) with self.settings(AUTHENTICATION_BACKENDS=['my.custom.backend']): errors = checks.run_checks() self.assertEqual(errors, [ checks.Warning( "'CustomUserNonUniqueUsername.username' is named as " "the 'USERNAME_FIELD', but it is not unique.", hint='Ensure that your authentication backend(s) can handle non-unique usernames.', obj=CustomUserNonUniqueUsername, id='auth.W004', ), ])