Repository: ocadotechnology/codeforlife-portal

Issue:
Registration page: fix form cleaning
500 Server error page pops up if users try to register again with same email address (form error message should pop up instead)


Discussion:

Resolving patch:
diff --git a/portal/emailMessages.py b/portal/emailMessages.py
--- a/portal/emailMessages.py
+++ b/portal/emailMessages.py
@@ -50,7 +50,7 @@ def emailVerificationNeededEmail(request, token):
         'subject': emailSubjectPrefix() + " : Email address verification needed",
         'message': ("Please go to " +
                     request.build_absolute_uri(reverse('verify_email', kwargs={'token': token})) +
-                    " to verify your email address" + emailBodySignOff(request)),
+                    " to verify your email address." + emailBodySignOff(request)),
     }
 
 
@@ -74,6 +74,17 @@ def emailChangeNotificationEmail(request, new_email):
     }
 
 
+def userAlreadyRegisteredEmail(request, email):
+    return {
+        'subject': emailSubjectPrefix() + " : Duplicate account error",
+        'message': ("A user is already registered with this email address: " +
+                    email + ".\nIf you've already registered, please login: " +
+                    request.build_absolute_uri(reverse('login_view')) + ".\n" +
+                    "Otherwise please register with a different email address." +
+                    emailBodySignOff(request)),
+    }
+
+
 def joinRequestPendingEmail(request, pendingAddress):
     return {
         'subject': emailSubjectPrefix() + " : School or club join request pending",
diff --git a/portal/forms/teach.py b/portal/forms/teach.py
--- a/portal/forms/teach.py
+++ b/portal/forms/teach.py
@@ -107,7 +107,7 @@ def clean_password(self):
 
         if password and not password_strength_test(password):
             raise forms.ValidationError(
-                "Password not strong enough, consider using at least 8 characters, upper and lower " + "case letters, and numbers")
+                "Password not strong enough, consider using at least 8 characters, upper and lower case letters, and numbers")
 
         return password
 
diff --git a/portal/views/home.py b/portal/views/home.py
--- a/portal/views/home.py
+++ b/portal/views/home.py
@@ -48,7 +48,7 @@
 from portal.models import Teacher, Class, Student
 from portal.forms.teach import TeacherSignupForm, TeacherLoginForm
 from portal.forms.play import StudentLoginForm, IndependentStudentLoginForm, StudentSignupForm
-from portal.helpers.emails import send_verification_email, is_verified, send_email, CONTACT_EMAIL
+from portal.helpers.emails import send_verification_email, is_verified, send_email, CONTACT_EMAIL, NOTIFICATION_EMAIL
 from portal.app_settings import CONTACT_FORM_EMAILS
 from portal.utils import using_two_factor
 from portal import app_settings, emailMessages
@@ -289,16 +289,26 @@ def process_indep_student_login_form(request, independent_student_login_form):
 
 
 def process_signup_form(request, data):
-    teacher = Teacher.objects.factory(
-        title=data['teacher_title'],
-        first_name=data['teacher_first_name'],
-        last_name=data['teacher_last_name'],
-        email=data['teacher_email'],
-        password=data['teacher_password'])
+    email = data['teacher_email']
+    teacher = None
 
-    send_verification_email(request, teacher.user.user)
+    if email and Teacher.objects.filter(new_user__email=email).exists():
+        email_message = emailMessages.userAlreadyRegisteredEmail(request, email)
+        send_email(NOTIFICATION_EMAIL, [email], email_message['subject'], email_message['message'])
+    else:
+        teacher = Teacher.objects.factory(
+            title=data['teacher_title'],
+            first_name=data['teacher_first_name'],
+            last_name=data['teacher_last_name'],
+            email=data['teacher_email'],
+            password=data['teacher_password'])
+
+        send_verification_email(request, teacher.user.user)
 
-    return render(request, 'portal/email_verification_needed.html', {'user': teacher.user.user})
+    if teacher:
+        return render(request, 'portal/email_verification_needed.html', {'user': teacher.user.user})
+    else:
+        return render(request, 'portal/email_verification_needed.html')
 
 
 def process_student_signup_form(request, data):


Test patch:
diff --git a/portal/tests/test_teacher.py b/portal/tests/test_teacher.py
--- a/portal/tests/test_teacher.py
+++ b/portal/tests/test_teacher.py
@@ -43,11 +43,12 @@
 
 from base_test import BaseTest
 from pageObjects.portal.home_page import HomePage
-from utils.teacher import signup_teacher, signup_teacher_directly
+from utils.teacher import signup_teacher, signup_teacher_directly, signup_duplicate_teacher_fail
 from utils.organisation import create_organisation_directly
 from utils.classes import create_class_directly
 from utils.student import create_school_student_directly
-from utils.messages import is_email_verified_message_showing, is_teacher_details_updated_message_showing, is_teacher_email_updated_message_showing
+from utils.messages import is_email_verified_message_showing, is_teacher_details_updated_message_showing, \
+    is_teacher_email_updated_message_showing
 from utils import email as email_utils
 
 
@@ -59,6 +60,17 @@ def test_signup(self):
         page, _, _ = signup_teacher(page)
         assert is_email_verified_message_showing(selenium)
 
+    def test_signup_duplicate_failure(self):
+        selenium.get(self.live_server_url)
+        page = HomePage(selenium)
+        page, email, _ = signup_teacher(page)
+        assert is_email_verified_message_showing(selenium)
+
+        selenium.get(self.live_server_url)
+        page = HomePage(selenium)
+        page, _, _ = signup_duplicate_teacher_fail(page, email)
+        assert page.__class__.__name__ == 'LoginPage'
+
     def test_login_failure(self):
         selenium.get(self.live_server_url)
         page = HomePage(selenium)
diff --git a/portal/tests/utils/email.py b/portal/tests/utils/email.py
--- a/portal/tests/utils/email.py
+++ b/portal/tests/utils/email.py
@@ -50,6 +50,12 @@ def follow_verify_email_link_to_login(page, email):
     return go_to_login_page(page.browser)
 
 
+def follow_duplicate_account_link_to_login(page, email):
+    _follow_duplicate_account_email_link(page, email)
+
+    return go_to_login_page(page.browser)
+
+
 def _follow_verify_email_link(page, email):
     message = str(email.message())
     prefix = '<p>Please go to <a href="'
@@ -59,6 +65,15 @@ def _follow_verify_email_link(page, email):
     page.browser.get(message[i:j])
 
 
+def _follow_duplicate_account_email_link(page, email):
+    message = str(email.message())
+    prefix = 'please login: <a href="'
+    i = string.find(message, prefix) + len(prefix)
+    suffix = '" rel="nofollow">'
+    j = string.find(message, suffix, i)
+    page.browser.get(message[i:j])
+
+
 def follow_reset_email_link(browser, email):
     message = str(email.body)
 
diff --git a/portal/tests/utils/teacher.py b/portal/tests/utils/teacher.py
--- a/portal/tests/utils/teacher.py
+++ b/portal/tests/utils/teacher.py
@@ -61,6 +61,20 @@ def signup_teacher_directly(**kwargs):
     return email_address, password
 
 
+def signup_duplicate_teacher_fail(page, duplicate_email):
+    page = page.go_to_signup_page()
+
+    title, first_name, last_name, email_address, password = generate_details()
+    page = page.signup(title, first_name, last_name, duplicate_email, password, password)
+
+    page = page.return_to_home_page()
+
+    page = email.follow_duplicate_account_link_to_login(page, mail.outbox[0])
+    mail.outbox = []
+
+    return page, email_address, password
+
+
 def signup_teacher(page):
     page = page.go_to_signup_page()