def test_high_security_required_toggle(self):
     required = [
         "username", "first_name", "last_name", "email", "nickname",
         "msisdn", "gender", "birth_date", "country", "avatar"
     ]
     form = RegistrationForm(data={}, security="high", required=required)
     self.assertFalse(form.is_valid())
     self.assertEqual(
         form.errors, {
             "username": ["This field is required."],
             "first_name": ["This field is required."],
             "last_name": ["This field is required."],
             "email": ["This field is required."],
             "nickname": ["This field is required."],
             "msisdn": ["This field is required."],
             "gender": ["This field is required."],
             "country": ["This field is required."],
             "avatar": ["This field is required."],
             "password1": ["This field is required."],
             "password2": ["This field is required."],
             "terms": ["This field is required."],
             "__all__": [
                 "Enter either email or msisdn",
                 "Enter either birth date or age"
             ]
         })
 def test_registration(self):
     form = RegistrationForm()
     html = form.as_div()
     for name, field in form.fields.items():
         # Terms is not rendered as part of the form html method
         if field.required and name is not "terms":
             self.assertIn("*", field.label)
             self.assertIn(field.label, html)
 def test_high_security_state(self):
     form = RegistrationForm(data={}, security="high")
     self.assertFalse(form.is_valid())
     self.assertIn("<li>Your password can&#39;t be too similar to your " \
     "other personal information.</li><li>Your password must contain at " \
     "least 8 characters.</li><li>Your password can&#39;t be a commonly " \
     "used password.</li><li>Your password can&#39;t be entirely numeric." \
     "</li><li>The password must contain at least one uppercase letter, " \
     "one lowercase one, a digit and special character.</li>", form.as_div())
 def test_min_required_age_dob(self):
     form = RegistrationForm(
         data={
             "username": "******",
             "email": "*****@*****.**",
             "birth_date": datetime.date.today() - relativedelta(years=10),
             "terms": True,
             "password1": "asdasdasdA@1",
             "password2": "asdasdasdA@1"
         })
     self.assertFalse(form.is_valid())
 def test_default_state(self):
     form = RegistrationForm(data={})
     self.assertFalse(form.is_valid())
     self.assertEqual(
         form.errors, {
             "username": ["This field is required."],
             "password1": ["This field is required."],
             "password2": ["This field is required."],
             "gender": ["This field is required."],
             "age": ["This field is required."],
             "terms": ["This field is required."],
         })
 def test_default_state(self):
     form = RegistrationForm(data={})
     self.assertFalse(form.is_valid())
     self.assertEqual(
         form.errors, {
             "username": ["This field is required."],
             "password1": ["This field is required."],
             "password2": ["This field is required."],
             "terms": ["This field is required."],
             "__all__": [
                 "Enter either email or msisdn",
                 "Enter either birth date or age"
             ]
         })
 def test_min_required_age(self):
     form = RegistrationForm(
         data={
             "username": "******",
             "email": "*****@*****.**",
             "age": constants.CONSENT_AGE - 1,
             "terms": True,
             "password1": "asdasdasdA@1",
             "password2": "asdasdasdA@1"
         })
     self.assertFalse(form.is_valid())
     self.assertEqual(form.errors, {
         "age": [
             "We are sorry, " \
             f"users under the age of {constants.CONSENT_AGE}" \
             " cannot create an account."
         ]
     })
     with mock.patch("authentication_service.forms.date") as mocked_date:
         mocked_date.today.return_value = datetime.date(2018, 1, 2)
         mocked_date.side_effect = lambda *args, **kw: datetime.date(
             *args, **kw)
         form = RegistrationForm(
             data={
                 "username": "******",
                 "email": "*****@*****.**",
                 "birth_date": datetime.date(2018 -
                                             constants.CONSENT_AGE, 1, 3),
                 "terms": True,
                 "password1": "asdasdasdA@1",
                 "password2": "asdasdasdA@1"
             })
         self.assertFalse(form.is_valid())
         form = RegistrationForm(
             data={
                 "username":
                 "******",
                 "email":
                 "*****@*****.**",
                 "birth_date":
                 datetime.date(2018 - constants.CONSENT_AGE + 1, 1, 3),
                 "terms":
                 True,
                 "password1":
                 "asdasdasdA@1",
                 "password2":
                 "asdasdasdA@1"
             })
         self.assertFalse(form.is_valid())
 def test_default_required_toggle_mapping(self):
     required = ["names", "picture"]
     form = RegistrationForm(data={}, required=required)
     self.assertFalse(form.is_valid())
     self.assertEqual(
         form.errors, {
             "username": ["This field is required."],
             "first_name": ["This field is required."],
             "last_name": ["This field is required."],
             "nickname": ["This field is required."],
             "avatar": ["This field is required."],
             "password1": ["This field is required."],
             "password2": ["This field is required."],
             "terms": ["This field is required."],
             "__all__": [
                 "Enter either email or msisdn",
                 "Enter either birth date or age"
             ]
         })
    def test_email_validation(self):
        user = get_user_model().objects.create_user(username="******",
                                                    email="*****@*****.**",
                                                    password="******",
                                                    birth_date=datetime.date(
                                                        2001, 1, 1))
        user.save()
        form = RegistrationForm(
            data={
                "username": "******",
                "email": "*****@*****.**",
                "birth_date": datetime.date(2000, 1, 1),
                "terms": True,
                "password1": "password",
                "password2": "password",
            })
        self.assertFalse(form.is_valid())
        self.assertEqual(form.errors, {
            "email": ["Core user with this Email address already exists."],
        })

        # Test users without emails do not cause validation errors.
        user = get_user_model().objects.create_user(username="******",
                                                    password="******",
                                                    birth_date=datetime.date(
                                                        2001, 1, 1))
        user.save()
        form = RegistrationForm(
            data={
                "username": "******",
                "password1": "password",
                "password2": "password",
                "msisdn": "0856545698",
                "terms": True,
                "birth_date": datetime.date(2000, 1, 1)
            })
        self.assertTrue(form.is_valid())
        form = RegistrationForm(
            data={
                "username": "******",
                "password1": "password",
                "password2": "password",
                "msisdn": "0856545698",
                "terms": True,
                "birth_date": datetime.date(2000, 1, 1)
            })
        self.assertTrue(form.is_valid())
    def test_age_to_birth_date(self):
        # Test age specified instead of birth_date. Refer to the link below for an explanation of
        # why the mocking is done the way it is:
        # http://www.voidspace.org.uk/python/mock/examples.html#partial-mocking
        with mock.patch("authentication_service.forms.date") as mocked_date:
            mocked_date.today.return_value = datetime.date(2000, 1, 2)
            mocked_date.side_effect = lambda *args, **kw: datetime.date(
                *args, **kw)

            form = RegistrationForm(data={
                "username": "******",
                "email": "*****@*****.**",
                "age": "16",
                "terms": True,
                "password1": "asdasdasdA@1",
                "password2": "asdasdasdA@1"
            },
                                    security="high")
            self.assertTrue(form.is_valid())
            self.assertEqual(form.cleaned_data["birth_date"],
                             datetime.date(1984, 1, 2))
 def test_on_required_age(self):
     form = RegistrationForm(
         data={
             "username": "******",
             "email": "*****@*****.**",
             "age": constants.CONSENT_AGE,
             "terms": True,
             "password1": "asdasdasdA@1",
             "password2": "asdasdasdA@1"
         })
     self.assertTrue(form.is_valid())
     with mock.patch("authentication_service.forms.date") as mocked_date:
         mocked_date.today.return_value = datetime.date(2018, 1, 2)
         mocked_date.side_effect = lambda *args, **kw: datetime.date(
             *args, **kw)
         form = RegistrationForm(
             data={
                 "username": "******",
                 "email": "*****@*****.**",
                 "birth_date": datetime.date(2018 -
                                             constants.CONSENT_AGE, 1, 2),
                 "terms": True,
                 "password1": "asdasdasdA@1",
                 "password2": "asdasdasdA@1"
             })
         self.assertTrue(form.is_valid())
 def test_unique_username(self):
     user = get_user_model().objects.create_user(username="******",
                                                 birth_date=datetime.date(
                                                     2000, 1, 1),
                                                 email="*****@*****.**",
                                                 gender="female",
                                                 email_verified=True)
     form = RegistrationForm(
         data={
             "username": user.username,
             "email": "*****@*****.**",
             "age": constants.CONSENT_AGE,
             "terms": True,
             "password1": "asdasdasdA@1",
             "password2": "asdasdasdA@1"
         })
     self.assertFalse(form.is_valid())
     self.assertEqual(
         form.errors, {
             "username": [
                 "Oh no! Looks like somebody else already took your username. "
                 "Please try something else, you get to choose an even cooler one this time!"
             ],
         })
    def test_default_settings(self):
        form = RegistrationForm(
            data={
                "username": "******",
                "password1": "password",
                "password2": "password",
                "gender": "none",
                "age": "16",
                "terms": True,
            })
        self.assertTrue(form.is_valid())

        form = RegistrationForm(
            data={
                "username": "******",
                "password1": "password",
                "password2": "password",
                "gender": "female",
                "age": "16",
                "terms": True,
            })
        self.assertTrue(form.is_valid())

        # Test valid with email
        form = RegistrationForm(
            data={
                "username": "******",
                "password1": "password",
                "password2": "password",
                "email": "*****@*****.**",
                "gender": "female",
                "age": "16",
                "terms": True,
            })
        self.assertTrue(form.is_valid())

        # Test valid with msisdn
        form = RegistrationForm(
            data={
                "username": "******",
                "password1": "password",
                "password2": "password",
                "msisdn": "0856545698",
                "gender": "female",
                "age": "16",
                "terms": True,
            })
        self.assertTrue(form.is_valid())

        # Test valid with both
        form = RegistrationForm(
            data={
                "username": "******",
                "password1": "password",
                "password2": "password",
                "email": "*****@*****.**",
                "msisdn": "0856545698",
                "birth_date": datetime.date(2000, 1, 1),
                "gender": "female",
                "age": "16",
                "terms": True,
            })
        self.assertTrue(form.is_valid())
    def test_default_password_validation(self):
        # Test both required
        form = RegistrationForm(
            data={
                "username": "******",
                "email": "*****@*****.**",
                "birth_date": datetime.date(2000, 1, 1),
                "password1": "password",
                "terms": True,
            })
        self.assertFalse(form.is_valid())
        self.assertEqual(form.errors, {
            "password2": ["This field is required."],
        })

        # Test both must match
        form = RegistrationForm(
            data={
                "username": "******",
                "email": "*****@*****.**",
                "birth_date": datetime.date(2000, 1, 1),
                "terms": True,
                "password1": "password",
                "password2": "password2"
            })
        self.assertFalse(form.is_valid())
        self.assertEqual(
            form.errors, {
                "password2":
                ["The two password fields don't match. Please try again."],
            })

        # Test min length
        form = RegistrationForm(
            data={
                "username": "******",
                "email": "*****@*****.**",
                "birth_date": datetime.date(2000, 1, 1),
                "terms": True,
                "password1": "123",
                "password2": "123"
            })
        self.assertFalse(form.is_valid())
        self.assertEqual(form.errors, {
            "password2": ["Password not long enough."],
        })

        # Test passwords happy
        form = RegistrationForm(
            data={
                "username": "******",
                "email": "*****@*****.**",
                "birth_date": datetime.date(2000, 1, 1),
                "terms": True,
                "password1": "1234",
                "password2": "1234"
            })
        self.assertTrue(form.is_valid())
        form.clean(
        )  # We need to clean the form to ensure birth_date is set appropriately
    def test_high_security_password_validation(self):
        # Test both required
        form = RegistrationForm(data={
            "username": "******",
            "birth_date": datetime.date(2000, 1, 1),
            "email": "*****@*****.**",
            "password1": "password",
            "terms": True,
        },
                                security="high")
        self.assertFalse(form.is_valid())
        self.assertEqual(form.errors, {
            "password2": ["This field is required."],
        })

        # Test both must match
        form = RegistrationForm(data={
            "username": "******",
            "email": "*****@*****.**",
            "birth_date": datetime.date(2000, 1, 1),
            "terms": True,
            "password1": "password",
            "password2": "password2"
        },
                                security="high")
        self.assertFalse(form.is_valid())
        self.assertEqual(
            form.errors, {
                "password2":
                ["The two password fields don't match. Please try again."],
            })

        # Test min length, unique validation and contains more than numeric
        form = RegistrationForm(data={
            "username": "******",
            "email": "*****@*****.**",
            "birth_date": datetime.date(2001, 1, 1),
            "terms": True,
            "password1": "123",
            "password2": "123"
        },
                                security="high")
        self.assertFalse(form.is_valid())
        self.assertEqual(
            form.errors, {
                "password2": [
                    "This password is too short. It must contain at least 8 characters.",
                    "This password is entirely numeric.",
                    "The password must contain at least one uppercase letter, "
                    "one lowercase one, a digit and special character."
                ]
            })

        # Test unique validation
        form = RegistrationForm(data={
            "username": "******",
            "email": "*****@*****.**",
            "birth_date": datetime.date(2000, 1, 1),
            "terms": True,
            "password1": "asdasdasd",
            "password2": "asdasdasd"
        },
                                security="high")
        self.assertFalse(form.is_valid())
        self.assertEqual(
            form.errors, {
                "password2": [
                    "The password must contain at least one uppercase letter, "
                    "one lowercase one, a digit and special character."
                ]
            })

        # Test close to username
        form = RegistrationForm(data={
            "username": "******",
            "email": "*****@*****.**",
            "birth_date": datetime.date(2000, 1, 1),
            "terms": True,
            "password1": "asdasdasd",
            "password2": "asdasdasd"
        },
                                security="high")
        self.assertFalse(form.is_valid())
        self.assertEqual(
            form.errors, {
                "password2": [
                    "The password is too similar to the username.",
                    "The password must contain at least one uppercase letter, "
                    "one lowercase one, a digit and special character."
                ]
            })

        # Test success
        form = RegistrationForm(data={
            "username": "******",
            "email": "*****@*****.**",
            "birth_date": datetime.date(2001, 1, 1),
            "terms": True,
            "password1": "asdasdasdA@1",
            "password2": "asdasdasdA@1"
        },
                                security="high")
        self.assertTrue(form.is_valid())
    def test_default_email_msisdn(self):
        # Test either is required
        form = RegistrationForm(
            data={
                "username": "******",
                "password1": "password",
                "password2": "password",
                "terms": True,
                "birth_date": datetime.date(2000, 1, 1)
            })
        self.assertFalse(form.is_valid())
        self.assertEqual(form.errors,
                         {"__all__": ["Enter either email or msisdn"]})

        # Test valid with email
        form = RegistrationForm(
            data={
                "username": "******",
                "password1": "password",
                "password2": "password",
                "email": "*****@*****.**",
                "terms": True,
                "birth_date": datetime.date(2000, 1, 1)
            })
        self.assertTrue(form.is_valid())

        # Test valid with msisdn
        form = RegistrationForm(
            data={
                "username": "******",
                "password1": "password",
                "password2": "password",
                "msisdn": "0856545698",
                "terms": True,
                "birth_date": datetime.date(2000, 1, 1)
            })
        self.assertTrue(form.is_valid())

        # Test valid with both
        form = RegistrationForm(
            data={
                "username": "******",
                "password1": "password",
                "password2": "password",
                "email": "*****@*****.**",
                "msisdn": "0856545698",
                "terms": True,
                "birth_date": datetime.date(2000, 1, 1)
            })
        self.assertTrue(form.is_valid())