Test driven development

In TDD, we first implement the test case before implementing the functionality in actual code. Therefore, we first write a test case that ll fail and then implement it

Consider the custom user model from previous sections and think of the functionalities we want to add

1) email address shoud be lower case

2) email address should not be empty

3) ability to create super user

Test cases : Think how the functionality should be implemented here

# checking case sensitive email
    def test_new_user_email_normalized(self):
        """we want email field to be unique for users
        But the second part of the email address is Case sensitive by Default
        ie, xyz@gmail.com and xyz@GMAIL.COM will be unique values
        So we change email to lower case"""

        email = "test@ABC.COM"
        user = get_user_model().objects.create_user(email, '1234')

        self.assertEqual(user.email, email.lower())

    # check if invalid Email raises ValueError
    def test_new_user_invalid_email(self):
        with self.assertRaises(ValueError):
            get_user_model().objects.create_user(None, '1234')

    # check if super user can be created
    def test_create_new_superuser(self):
        user = get_user_model().objects.create_superuser(
            'aravind@gmail.com',
            '1234'
        )

        self.assertTrue(user.is_superuser)
        self.assertTrue(user.is_staff)

Add checks for email and create a method in UserManager to create superuser

# Creating CUSTOM USER MODEL
    class UserManager(BaseUserManager):
        """Default User model requires mandatory username field
        But we dont want it that way. So we create custom User model"""

        def create_user(self, email, password=None, **kwargs):
            """Creates and saves a new user and returns the user model"""

            # this creates a model with mandatory email field
            if not email:
                raise ValueError('Usersmust have email')
            # normalize_email is under BaseUSerManager.
            # It makes just domain part of email to lower case
            user = self.model(email=self.normalize_email(email), **kwargs)
            user.set_password(password)
            user.save(using=self._db)

            return user

        def create_superuser(self, email, password):
            user = self.create_user(email, password)
            user.is_staff = True
            user.is_superuser = True
            user.save(using=self._db)

            return user