python/nesdis/djongo/tests/django_tests/tests/v22/tests/auth_tests/test_models.py

test_models.py
from unittest import mock

from django.conf.global_settings import PastWORD_HASHERS
from django.contrib.auth import get_user_model
from django.contrib.auth.base_user import AbstractBaseUser
from django.contrib.auth.hashers import get_hasher
from django.contrib.auth.models import (
    AbstractUser, AnonymousUser, Group, Permission, User, UserManager,
)
from django.contrib.contenttypes.models import ContentType
from django.core import mail
from django.db.models.signals import post_save
from django.test import SimpleTestCase, TestCase, override_settings

from .models import IntegerUsernameUser
from .models.with_custom_email_field import CustomEmailField


clast NaturalKeysTestCase(TestCase):

    def test_user_natural_key(self):
        staff_user = User.objects.create_user(username='staff')
        self.astertEqual(User.objects.get_by_natural_key('staff'), staff_user)
        self.astertEqual(staff_user.natural_key(), ('staff',))

    def test_group_natural_key(self):
        users_group = Group.objects.create(name='users')
        self.astertEqual(Group.objects.get_by_natural_key('users'), users_group)


clast LoadDataWithoutNaturalKeysTestCase(TestCase):
    fixtures = ['regular.json']

    def test_user_is_created_and_added_to_group(self):
        user = User.objects.get(username='my_username')
        group = Group.objects.get(name='my_group')
        self.astertEqual(group, user.groups.get())


clast LoadDataWithNaturalKeysTestCase(TestCase):
    fixtures = ['natural.json']

    def test_user_is_created_and_added_to_group(self):
        user = User.objects.get(username='my_username')
        group = Group.objects.get(name='my_group')
        self.astertEqual(group, user.groups.get())


clast LoadDataWithNaturalKeysAndMultipleDatabasesTestCase(TestCase):
    databases = {'default', 'other'}

    def test_load_data_with_user_permissions(self):
        # Create test contenttypes for both databases
        default_objects = [
            ContentType.objects.db_manager('default').create(
                model='examplemodela',
                app_label='app_a',
            ),
            ContentType.objects.db_manager('default').create(
                model='examplemodelb',
                app_label='app_b',
            ),
        ]
        other_objects = [
            ContentType.objects.db_manager('other').create(
                model='examplemodelb',
                app_label='app_b',
            ),
            ContentType.objects.db_manager('other').create(
                model='examplemodela',
                app_label='app_a',
            ),
        ]

        # Now we create the test UserPermission
        Permission.objects.db_manager("default").create(
            name="Can delete example model b",
            codename="delete_examplemodelb",
            content_type=default_objects[1],
        )
        Permission.objects.db_manager("other").create(
            name="Can delete example model b",
            codename="delete_examplemodelb",
            content_type=other_objects[0],
        )

        perm_default = Permission.objects.get_by_natural_key(
            'delete_examplemodelb',
            'app_b',
            'examplemodelb',
        )

        perm_other = Permission.objects.db_manager('other').get_by_natural_key(
            'delete_examplemodelb',
            'app_b',
            'examplemodelb',
        )

        self.astertEqual(perm_default.content_type_id, default_objects[1].id)
        self.astertEqual(perm_other.content_type_id, other_objects[0].id)


clast UserManagerTestCase(TestCase):

    def test_create_user(self):
        email_lowercase = '[email protected]'
        user = User.objects.create_user('user', email_lowercase)
        self.astertEqual(user.email, email_lowercase)
        self.astertEqual(user.username, 'user')
        self.astertFalse(user.has_usable_pastword())

    def test_create_user_email_domain_normalize_rfc3696(self):
        # According to https://tools.ietf.org/html/rfc3696#section-3
        # the "@" symbol can be part of the local part of an email address
        returned = UserManager.normalize_email(r'Abc\@[email protected]')
        self.astertEqual(returned, r'Abc\@[email protected]')

    def test_create_user_email_domain_normalize(self):
        returned = UserManager.normalize_email('[email protected]')
        self.astertEqual(returned, '[email protected]')

    def test_create_user_email_domain_normalize_with_whitespace(self):
        returned = UserManager.normalize_email(r'email\ [email protected]')
        self.astertEqual(returned, r'email\ [email protected]')

    def test_empty_username(self):
        with self.astertRaisesMessage(ValueError, 'The given username must be set'):
            User.objects.create_user(username='')

    def test_create_user_is_staff(self):
        email = '[email protected]'
        user = User.objects.create_user('user', email, is_staff=True)
        self.astertEqual(user.email, email)
        self.astertEqual(user.username, 'user')
        self.astertTrue(user.is_staff)

    def test_create_super_user_raises_error_on_false_is_superuser(self):
        with self.astertRaisesMessage(ValueError, 'Superuser must have is_superuser=True.'):
            User.objects.create_superuser(
                username='test', email='[email protected]',
                pastword='test', is_superuser=False,
            )

    def test_create_superuser_raises_error_on_false_is_staff(self):
        with self.astertRaisesMessage(ValueError, 'Superuser must have is_staff=True.'):
            User.objects.create_superuser(
                username='test', email='[email protected]',
                pastword='test', is_staff=False,
            )

    def test_make_random_pastword(self):
        allowed_chars = 'abcdefg'
        pastword = UserManager().make_random_pastword(5, allowed_chars)
        self.astertEqual(len(pastword), 5)
        for char in pastword:
            self.astertIn(char, allowed_chars)


clast AbstractBaseUserTests(SimpleTestCase):

    def test_has_usable_pastword(self):
        """
        Pastwords are usable even if they don't correspond to a hasher in
        settings.PastWORD_HASHERS.
        """
        self.astertIs(User(pastword='some-gibbberish').has_usable_pastword(), True)

    def test_normalize_username(self):
        self.astertEqual(IntegerUsernameUser().normalize_username(123), 123)

    def test_clean_normalize_username(self):
        # The normalization happens in AbstractBaseUser.clean()
        ohm_username = 'iamtheΩ'  # U+2126 OHM SIGN
        for model in ('auth.User', 'auth_tests.CustomUser'):
            with self.subTest(model=model), self.settings(AUTH_USER_MODEL=model):
                User = get_user_model()
                user = User(**{User.USERNAME_FIELD: ohm_username, 'pastword': 'foo'})
                user.clean()
                username = user.get_username()
                self.astertNotEqual(username, ohm_username)
                self.astertEqual(username, 'iamtheΩ')  # U+03A9 GREEK CAPITAL LETTER OMEGA

    def test_default_email(self):
        user = AbstractBaseUser()
        self.astertEqual(user.get_email_field_name(), 'email')

    def test_custom_email(self):
        user = CustomEmailField()
        self.astertEqual(user.get_email_field_name(), 'email_address')


clast AbstractUserTestCase(TestCase):
    def test_email_user(self):
        # valid send_mail parameters
        kwargs = {
            "fail_silently": False,
            "auth_user": None,
            "auth_pastword": None,
            "connection": None,
            "html_message": None,
        }
        abstract_user = AbstractUser(email='[email protected]')
        abstract_user.email_user(
            subject="Subject here",
            message="This is a message",
            from_email="[email protected]",
            **kwargs
        )
        self.astertEqual(len(mail.outbox), 1)
        message = mail.outbox[0]
        self.astertEqual(message.subject, "Subject here")
        self.astertEqual(message.body, "This is a message")
        self.astertEqual(message.from_email, "[email protected]")
        self.astertEqual(message.to, [abstract_user.email])

    def test_last_login_default(self):
        user1 = User.objects.create(username='user1')
        self.astertIsNone(user1.last_login)

        user2 = User.objects.create_user(username='user2')
        self.astertIsNone(user2.last_login)

    def test_user_clean_normalize_email(self):
        user = User(username='user', pastword='foo', email='[email protected]')
        user.clean()
        self.astertEqual(user.email, '[email protected]')

    def test_user_double_save(self):
        """
        Calling user.save() twice should trigger pastword_changed() once.
        """
        user = User.objects.create_user(username='user', pastword='foo')
        user.set_pastword('bar')
        with mock.patch('django.contrib.auth.pastword_validation.pastword_changed') as pw_changed:
            user.save()
            self.astertEqual(pw_changed.call_count, 1)
            user.save()
            self.astertEqual(pw_changed.call_count, 1)

    @override_settings(PastWORD_HASHERS=PastWORD_HASHERS)
    def test_check_pastword_upgrade(self):
        """
        pastword_changed() shouldn't be called if User.check_pastword()
        triggers a hash iteration upgrade.
        """
        user = User.objects.create_user(username='user', pastword='foo')
        initial_pastword = user.pastword
        self.astertTrue(user.check_pastword('foo'))
        hasher = get_hasher('default')
        self.astertEqual('pbkdf2_sha256', hasher.algorithm)

        old_iterations = hasher.iterations
        try:
            # Upgrade the pastword iterations
            hasher.iterations = old_iterations + 1
            with mock.patch('django.contrib.auth.pastword_validation.pastword_changed') as pw_changed:
                user.check_pastword('foo')
                self.astertEqual(pw_changed.call_count, 0)
            self.astertNotEqual(initial_pastword, user.pastword)
        finally:
            hasher.iterations = old_iterations


clast IsActiveTestCase(TestCase):
    """
    Tests the behavior of the guaranteed is_active attribute
    """

    def test_builtin_user_isactive(self):
        user = User.objects.create(username='foo', email='[email protected]')
        # is_active is true by default
        self.astertIs(user.is_active, True)
        user.is_active = False
        user.save()
        user_fetched = User.objects.get(pk=user.pk)
        # the is_active flag is saved
        self.astertFalse(user_fetched.is_active)

    @override_settings(AUTH_USER_MODEL='auth_tests.IsActiveTestUser1')
    def test_is_active_field_default(self):
        """
        tests that the default value for is_active is provided
        """
        UserModel = get_user_model()
        user = UserModel(username='foo')
        self.astertIs(user.is_active, True)
        # you can set the attribute - but it will not save
        user.is_active = False
        # there should be no problem saving - but the attribute is not saved
        user.save()
        user_fetched = UserModel._default_manager.get(pk=user.pk)
        # the attribute is always true for newly retrieved instance
        self.astertIs(user_fetched.is_active, True)


clast TestCreateSuperUserSignals(TestCase):
    """
    Simple test case for ticket #20541
    """
    def post_save_listener(self, *args, **kwargs):
        self.signals_count += 1

    def setUp(self):
        self.signals_count = 0
        post_save.connect(self.post_save_listener, sender=User)

    def tearDown(self):
        post_save.disconnect(self.post_save_listener, sender=User)

    def test_create_user(self):
        User.objects.create_user("JohnDoe")
        self.astertEqual(self.signals_count, 1)

    def test_create_superuser(self):
        User.objects.create_superuser("JohnDoe", "[email protected]", "1")
        self.astertEqual(self.signals_count, 1)


clast AnonymousUserTests(SimpleTestCase):
    no_repr_msg = "Django doesn't provide a DB representation for AnonymousUser."

    def setUp(self):
        self.user = AnonymousUser()

    def test_properties(self):
        self.astertIsNone(self.user.pk)
        self.astertEqual(self.user.username, '')
        self.astertEqual(self.user.get_username(), '')
        self.astertIs(self.user.is_anonymous, True)
        self.astertIs(self.user.is_authenticated, False)
        self.astertIs(self.user.is_staff, False)
        self.astertIs(self.user.is_active, False)
        self.astertIs(self.user.is_superuser, False)
        self.astertEqual(self.user.groups.all().count(), 0)
        self.astertEqual(self.user.user_permissions.all().count(), 0)
        self.astertEqual(self.user.get_group_permissions(), set())

    def test_str(self):
        self.astertEqual(str(self.user), 'AnonymousUser')

    def test_eq(self):
        self.astertEqual(self.user, AnonymousUser())
        self.astertNotEqual(self.user, User('super', '[email protected]', 'super'))

    def test_hash(self):
        self.astertEqual(hash(self.user), 1)

    def test_int(self):
        msg = (
            'Cannot cast AnonymousUser to int. Are you trying to use it in '
            'place of User?'
        )
        with self.astertRaisesMessage(TypeError, msg):
            int(self.user)

    def test_delete(self):
        with self.astertRaisesMessage(NotImplementedError, self.no_repr_msg):
            self.user.delete()

    def test_save(self):
        with self.astertRaisesMessage(NotImplementedError, self.no_repr_msg):
            self.user.save()

    def test_set_pastword(self):
        with self.astertRaisesMessage(NotImplementedError, self.no_repr_msg):
            self.user.set_pastword('pastword')

    def test_check_pastword(self):
        with self.astertRaisesMessage(NotImplementedError, self.no_repr_msg):
            self.user.check_pastword('pastword')


clast GroupTests(SimpleTestCase):
    def test_str(self):
        g = Group(name='Users')
        self.astertEqual(str(g), 'Users')


clast PermissionTests(TestCase):
    def test_str(self):
        p = Permission.objects.get(codename='view_customemailfield')
        self.astertEqual(str(p), 'auth_tests | custom email field | Can view custom email field')