def test_repr(): """ The string representation of an email address should contain all the information needed to reconstruct the instance. """ email = models.EmailAddress( address="*****@*****.**", time_created=timezone.now(), time_updated=timezone.now(), time_verified=timezone.now(), user=auth.get_user_model()(), ) expected = test_utils.create_expected_repr( email, [ "address", "id", "is_verified", "time_created", "time_updated", "time_verified", "user", ], ) assert repr(email) == expected
def test_send_email_with_verification_url( mock_now, mock_send_email, _, settings ): """ This method should send the email verification token to the associated email address and record the send time of the email. """ verification_url = "example.com/verify/{key}" settings.EMAIL_AUTH = {"EMAIL_VERIFICATION_URL": verification_url} user = get_user_model()() email = models.EmailAddress(address="*****@*****.**", user=user) verification = models.EmailVerification(email=email) verification.send_email() assert mock_send_email.call_args[1] == { "context": { "email": email, "user": user, "verification": verification, "verification_url": verification_url.format( key=verification.token ), }, "from_email": django_settings.DEFAULT_FROM_EMAIL, "recipient_list": [email.address], "subject": "Please Verify Your Email Address", "template_name": "email_auth/emails/verify-email", } assert verification.time_sent == mock_now.return_value assert verification.save.call_count == 1
def test_send_email_with_reset_url(mock_now, mock_send_email, _, settings): """ This method should send the password reset token to the associated email address and record the send time of the email. """ reset_url_template = "example.com/reset-password/{key}" settings.EMAIL_AUTH = {"PASSWORD_RESET_URL": reset_url_template} email = models.EmailAddress(address="*****@*****.**") password_reset = models.PasswordReset(email=email) password_reset.send_email() assert mock_send_email.call_args[1] == { "context": { "password_reset": password_reset, "reset_url": reset_url_template.format(key=password_reset.token), }, "from_email": django_settings.DEFAULT_FROM_EMAIL, "recipient_list": [email.address], "subject": "Reset Your Password", "template_name": "email_auth/emails/reset-password", } assert password_reset.time_sent == mock_now.return_value assert password_reset.save.call_count == 1
def test_str(): """ Converting an email address to a string should return the address text as specified by the owner. """ email = models.EmailAddress(address="*****@*****.**") assert str(email) == email.address
def test_init_with_all_fields(): """ Test creating a new password reset with all fields that aren't automatically populated. """ password_reset = models.PasswordReset(email=models.EmailAddress()) assert password_reset.pk assert password_reset.token
def test_verify(mock_now): email = models.EmailAddress() with mock.patch.object(email, "save", autospec=True) as mock_save: email.verify() assert email.is_verified assert email.time_verified == mock_now.return_value assert mock_save.call_count == 1
def test_init_all_fields(): """ Test creating an email verification with all allowed fields. """ verification = models.EmailVerification( email=models.EmailAddress(), time_sent=timezone.now() ) assert verification.pk
def test_send_verification_email(*_): """ This method should create a new verification token for the address and send it to the user. """ email = models.EmailAddress(address="*****@*****.**") verification = email.send_verification_email() assert verification.save.call_count == 1 assert verification.send_email.call_count == 1
def test_str(): """ Converting a password reset to a string should return a message including the email address the token is associated with. """ email = models.EmailAddress(address="*****@*****.**") password_reset = models.PasswordReset(email=email) expected = f"Password reset for '{email}'" assert str(password_reset) == expected
def test_str(): """ Converting a verification instance to a string should return a message stating which email address the verification is for. """ email = models.EmailAddress(address="*****@*****.**") verification = models.EmailVerification(email=email) expected = f"Verification for {email}" assert str(verification) == expected
def test_init_with_all_fields(): """ Test the fields allowed for an email address. """ email = models.EmailAddress( address="*****@*****.**", is_verified=True, time_verified=timezone.now(), user=auth.get_user_model()(), ) # Default fields should be populated assert email.pk
def test_send_already_verified(mock_send_email): """ This method should send a notification to the email address letting the user know their email address is already verified. """ email = models.EmailAddress(address="*****@*****.**") email.send_already_verified() assert mock_send_email.call_args[1] == { "context": {"email": email}, "from_email": settings.DEFAULT_FROM_EMAIL, "recipient_list": [email.address], "subject": "Your Email Address has Already Been Verified", "template_name": "email_auth/emails/already-verified", }
def test_authenticate_with_verified_email_correct_password_inactive_user( mock_email_address_qs): """ If the user provides valid credentials but is inactive, authentication should fail. """ password = "******" user = get_user_model()(is_active=False) user.set_password(password) email = models.EmailAddress(address="*****@*****.**", user=user) mock_email_address_qs.get.return_value = email backend = authentication.VerifiedEmailBackend() authenticated_user = backend.authenticate(None, email.address, password) assert authenticated_user is None
def test_send_duplicate_notification(mock_send_email): """ This method should send a notification to the email address letting the user know another attempt was made to register the email address. """ email = models.EmailAddress(address="*****@*****.**") email.send_duplicate_notification() assert mock_send_email.call_args[1] == { "context": {"email": email}, "from_email": settings.DEFAULT_FROM_EMAIL, "recipient_list": [email.address], "subject": "Your Email Address has Already Been Registered", "template_name": "email_auth/emails/duplicate-email", }
def test_authenticate_with_verified_email_incorrect_password( mock_email_address_qs): """ If the user provides a verified email address but the provided password does not match the owner of the email address, authentication should fail. """ password = "******" user = get_user_model()(is_active=True) user.set_password(password + "invalid") email = models.EmailAddress(address="*****@*****.**", user=user) mock_email_address_qs.get.return_value = email backend = authentication.VerifiedEmailBackend() authenticated_user = backend.authenticate(None, email.address, password) assert authenticated_user is None
def test_verify(): """ Verifying an instance should mark the associated email as verified and delete the verification instance. """ email = models.EmailAddress() verification = models.EmailVerification(email=email) with mock.patch.object( email, "verify", autospec=True ) as mock_verify, mock.patch.object( verification, "delete", autospec=True ) as mock_delete: verification.verify() assert mock_verify.call_count == 1 assert mock_delete.call_count == 1
def test_repr(): """ The string representation of an instance should contain all the information necessary to recreate it. """ email = models.EmailAddress( address="*****@*****.**", user=get_user_model()() ) verification = models.EmailVerification( email=email, time_sent=timezone.now() ) expected = test_utils.create_expected_repr( verification, ["email", "time_created", "time_sent", "time_updated", "token"], ) assert repr(verification) == expected
def test_authenticate_with_verified_email_correct_password( mock_email_address_qs): """ If a verified email address and the password of the user who owns the email address are provided, the authentication method should return the owner of the email address. """ password = "******" user = get_user_model()(is_active=True) user.set_password(password) email = models.EmailAddress(address="*****@*****.**", user=user) mock_email_address_qs.get.return_value = email backend = authentication.VerifiedEmailBackend() authenticated_user = backend.authenticate(None, email.address, password) assert authenticated_user == user assert mock_email_address_qs.get.call_args[1]["address"] == email.address
def test_repr(): """ The string representation of a token should contain all the fields required to reconstruct it. """ user = get_user_model()() email = models.EmailAddress(user=user) password_reset = models.PasswordReset( email=email, time_created=timezone.now(), time_sent=timezone.now(), time_updated=timezone.now(), ) expected = test_utils.create_expected_repr( password_reset, ["email", "time_created", "time_sent", "time_updated", "token"], ) assert repr(password_reset) == expected
def test_save_verified_email(_, mock_email_address_qs): """ Saving the serializer with an email address that has already been verified should send the user a notification that their email has already been verified. """ email = models.EmailAddress(address="*****@*****.**", is_verified=True) mock_email_address_qs.get.return_value = email data = {"email": email.address} serializer = serializers.EmailVerificationRequestSerializer(data=data) assert serializer.is_valid() verification = serializer.save() assert mock_email_address_qs.get.call_args[1] == { "address__iexact": email.address } assert verification is None assert email.send_already_verified.call_count == 1
def test_save_unverified_email(_, mock_email_address_qs): """ Saving the serializer with an address that exists in the database but has not yet been verified should send a new verification email to the provided address. """ email = models.EmailAddress(address="*****@*****.**", is_verified=False) mock_email_address_qs.get.return_value = email data = {"email": email.address} serializer = serializers.EmailVerificationRequestSerializer(data=data) assert serializer.is_valid() verification = serializer.save() assert mock_email_address_qs.get.call_args[1] == { "address__iexact": email.address } assert verification.email == email assert verification.send_email.call_count == 1
def test_save_verified_email(_, mock_email_address_qs): """ If a verified email is provided, saving the serializer should send a new password reset token to the provided address. """ email = models.EmailAddress(address="*****@*****.**") mock_email_address_qs.get.return_value = email data = {"email": email.address} serializer = serializers.PasswordResetRequestSerializer(data=data) assert serializer.is_valid() result = serializer.save() assert serializer.data == data assert result.send_email.call_count == 1 assert mock_email_address_qs.get.call_args[1] == { "address__iexact": email.address, "is_verified": True, }