From eea7e73ddb773b53af4530b218c78eedc9cb455a Mon Sep 17 00:00:00 2001 From: Sarah Boyce <42296566+sarahboyce@users.noreply.github.com> Date: Sun, 31 Mar 2024 19:00:35 +0200 Subject: [PATCH] Add resend email confirmation flow. (#368) --- .../tests/test_resend_confirmation_email.py | 38 +++++++++++++++++++ accounts/tests/test_signup_view.py | 4 +- accounts/urls.py | 6 +++ accounts/views.py | 14 ++++++- .../includes/email_confirmed_warning.html | 3 +- indymeet/templates/includes/messages.html | 20 +++------- .../resend_confirmation_email_button.html | 5 +++ indymeet/templates/registration/profile.html | 1 + 8 files changed, 72 insertions(+), 19 deletions(-) create mode 100644 accounts/tests/test_resend_confirmation_email.py create mode 100644 indymeet/templates/includes/resend_confirmation_email_button.html diff --git a/accounts/tests/test_resend_confirmation_email.py b/accounts/tests/test_resend_confirmation_email.py new file mode 100644 index 00000000..b8938599 --- /dev/null +++ b/accounts/tests/test_resend_confirmation_email.py @@ -0,0 +1,38 @@ +from __future__ import annotations + +from django.core import mail +from django.test import Client +from django.test import TestCase +from django.urls import reverse + +from accounts.factories import UserFactory + + +class ResendConfirmationEmailViewTests(TestCase): + def setUp(self): + self.client = Client() + + @classmethod + def setUpTestData(cls): + cls.user = UserFactory.create() + cls.resend_confirmation_email_url = reverse("resend_email_confirmation") + + def test_must_be_authentication(self): + response = self.client.post(self.resend_confirmation_email_url, {}, follow=True) + self.assertRedirects( + response, + f"{reverse('login')}?next={self.resend_confirmation_email_url}", + ) + + def test_get_update_email_subscription_url(self): + self.client.force_login(self.user) + response = self.client.post(self.resend_confirmation_email_url, {}, follow=True) + self.assertEqual(response.status_code, 200) + self.assertContains(response, "Profile Info") + self.assertContains(response, "A verification email has been sent") + self.assertEqual(len(mail.outbox), 1) + self.assertEqual(mail.outbox[0].subject, "Djangonaut Space Email Confirmation") + self.assertIn( + "Thank you for signing up to Djangonaut Space! Click the link to verify your email:", + mail.outbox[0].body, + ) diff --git a/accounts/tests/test_signup_view.py b/accounts/tests/test_signup_view.py index e57d996d..3df3d3b3 100644 --- a/accounts/tests/test_signup_view.py +++ b/accounts/tests/test_signup_view.py @@ -50,9 +50,7 @@ def test_signup_template_post_success(self, mock_captcha): ), ) self.assertEqual(len(mail.outbox), 1) - self.assertEqual( - mail.outbox[0].subject, "Djangonaut Space Registration Confirmation" - ) + self.assertEqual(mail.outbox[0].subject, "Djangonaut Space Email Confirmation") self.assertIn( "Thank you for signing up to Djangonaut Space! Click the link to verify your email:", mail.outbox[0].body, diff --git a/accounts/urls.py b/accounts/urls.py index edd0627b..92fbba16 100644 --- a/accounts/urls.py +++ b/accounts/urls.py @@ -7,6 +7,7 @@ from .views import ActivateAccountView from .views import CustomPasswordResetView from .views import profile +from .views import ResendConfirmationEmailView from .views import SignUpView from .views import UpdateEmailSubscriptionView from .views import UpdateUserView @@ -31,6 +32,11 @@ ActivateAccountView.as_view(), name="activate_account", ), + path( + "resend_email_confirmation/", + ResendConfirmationEmailView.as_view(), + name="resend_email_confirmation", + ), path( "email_subscriptions/", UpdateEmailSubscriptionView.as_view(), diff --git a/accounts/views.py b/accounts/views.py index 40824b6a..fa6ec66a 100644 --- a/accounts/views.py +++ b/accounts/views.py @@ -69,7 +69,7 @@ def send_user_confirmation_email(request, user): "unsubscribe_link": request.build_absolute_uri(unsubscribe_link), } send_mail( - "Djangonaut Space Registration Confirmation", + "Djangonaut Space Email Confirmation", render_to_string("emails/email_confirmation.txt", email_dict), settings.DEFAULT_FROM_EMAIL, [user.email], @@ -121,6 +121,18 @@ def profile(request): return render(request, "registration/profile.html") +class ResendConfirmationEmailView(LoginRequiredMixin, View): + def post(self, request): + user = request.user + send_user_confirmation_email(request, user) + messages.add_message( + request, + messages.SUCCESS, + f"A verification email has been sent to {user.email}", + ) + return redirect("profile") + + class UpdateUserView(LoginRequiredMixin, UpdateView): form_class = CustomUserChangeForm template_name = "registration/update_user.html" diff --git a/home/templates/home/includes/email_confirmed_warning.html b/home/templates/home/includes/email_confirmed_warning.html index c81f142e..9d61d787 100644 --- a/home/templates/home/includes/email_confirmed_warning.html +++ b/home/templates/home/includes/email_confirmed_warning.html @@ -1,6 +1,7 @@ {% if request.user.is_authenticated and not request.user.profile.email_confirmed %} -