Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Deverify released students, send new verify email and update join request error message #2313

Merged
merged 5 commits into from
May 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 18 additions & 10 deletions cfl_common/common/helpers/emails.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import datetime
import json
import re
from enum import Enum, auto
from uuid import uuid4

Expand Down Expand Up @@ -66,13 +65,14 @@ def send_email(
django_send_email(sender, recipients, subject, text_content, title, replace_url, plaintext_template, html_template)


def send_verification_email(request, user, data, new_email=None, age=None):
def send_verification_email(request, user, data, new_email=None, age=None, school=None):
"""
Sends emails relating to email address verification.

On registration:
- if the user is under 13, send a verification email addressed to the parent / guardian
- if the user is over 13, send a regular verification email
- if the user is a student who just got released, send a verification email explaining the situation
- if the user is a student who has requested to sign up to the newsletter, handle their Dotmailer subscription

On email address update:
Expand All @@ -88,20 +88,28 @@ def send_verification_email(request, user, data, new_email=None, age=None):
student)
"""

# verifying first email address (registration)
# verifying first email address (registration or unverified login attempt)
if not new_email:
verification = generate_token(user)

# if the user is a teacher
if age is None:
url = f"{request.build_absolute_uri(reverse('verify_email', kwargs={'token': verification}))}"
# if the user is a released student
if hasattr(user, "new_student") and school is not None:
url = f"{request.build_absolute_uri(reverse('verify_email', kwargs={'token': verification}))}"

send_dotdigital_email(
campaign_ids["verify_released_student"], [user.email],
personalization_values={"VERIFICATION_LINK": url, "SCHOOL_NAME": school.name}
)
else:
url = f"{request.build_absolute_uri(reverse('verify_email', kwargs={'token': verification}))}"

send_dotdigital_email(
campaign_ids["verify_new_user"], [user.email], personalization_values={"VERIFICATION_LINK": url}
)
send_dotdigital_email(
campaign_ids["verify_new_user"], [user.email], personalization_values={"VERIFICATION_LINK": url}
)

if _newsletter_ticked(data):
add_to_dotmailer(user.first_name, user.last_name, user.email, DotmailerUserType.TEACHER)
if _newsletter_ticked(data):
add_to_dotmailer(user.first_name, user.last_name, user.email, DotmailerUserType.TEACHER)
# if the user is an independent student
else:
if age < 13:
Expand Down
1 change: 1 addition & 0 deletions cfl_common/common/mail.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"verify_new_user_first_reminder": 1557170,
"verify_new_user_second_reminder": 1557173,
"verify_new_user_via_parent": 1551587,
"verify_released_student": 1580574,
}


Expand Down
16 changes: 10 additions & 6 deletions portal/forms/play.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,15 +277,19 @@ class StudentJoinOrganisationForm(forms.Form):

def clean(self):
access_code = self.cleaned_data.get("access_code", None)
join_error_text = "The class code you entered either does not exist or is not currently accepting join requests. Please double check that you have entered the correct class code and contact the teacher of the class to ensure their class is currently accepting join requests."

if access_code:
classes = Class.objects.filter(access_code=access_code)
if len(classes) != 1:
raise forms.ValidationError("Cannot find the school or club and/or class")
raise forms.ValidationError(join_error_text)

self.klass = classes[0]
if not self.klass.always_accept_requests:
if self.klass.accept_requests_until is None:
raise forms.ValidationError("Cannot find the school or club and/or class")
elif (self.klass.accept_requests_until - timezone.now()) < timedelta():
raise forms.ValidationError("Cannot find the school or club and/or class")

if not self.klass.always_accept_requests and (
self.klass.accept_requests_until is None
or self.klass.accept_requests_until - timezone.now()
< timedelta()
):
raise forms.ValidationError(join_error_text)
return self.cleaned_data
10 changes: 7 additions & 3 deletions portal/tests/test_independent_student.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ def test_login_not_verified(self, mock_send_dotdigital_email):
page = page.go_to_independent_student_login_page()
page = page.independent_student_login_failure(username, password)

errors = page.has_login_failed("independent_student_login_form", INVALID_LOGIN_MESSAGE)
page.has_login_failed("independent_student_login_form", INVALID_LOGIN_MESSAGE)
assert page.has_login_failed("independent_student_login_form", INVALID_LOGIN_MESSAGE)

verification_url = mock_send_dotdigital_email.call_args.kwargs["personalization_values"]["VERIFICATION_LINK"]
Expand Down Expand Up @@ -471,7 +471,9 @@ def test_join_class_nonexistent_class(self):
)

assert self.is_join_class_page(page)
assert page.has_join_request_failed("Cannot find the school or club and/or class")
assert page.has_join_request_failed(
"The class code you entered either does not exist or is not currently accepting join requests. Please double check that you have entered the correct class code and contact the teacher of the class to ensure their class is currently accepting join requests."
)

def test_join_class_not_accepting_requests(self):
teacher_email, _ = signup_teacher_directly()
Expand All @@ -490,7 +492,9 @@ def test_join_class_not_accepting_requests(self):
)

assert self.is_join_class_page(page)
assert page.has_join_request_failed("Cannot find the school or club and/or class")
assert page.has_join_request_failed(
"The class code you entered either does not exist or is not currently accepting join requests. Please double check that you have entered the correct class code and contact the teacher of the class to ensure their class is currently accepting join requests."
)

def test_join_class_revoked(self):
teacher_email, _ = signup_teacher_directly()
Expand Down
Loading
Loading