Commit 6ab8a856 by Will Daly

Merge pull request #5640 from edx/will/open-source-tos

Support separate terms of service and honor code checkboxes.
parents a35ce365 d774bcf3
......@@ -983,6 +983,78 @@ class RegistrationViewTest(ApiTestCase):
}
)
@override_settings(MKTG_URLS={
"ROOT": "https://www.test.com/",
"HONOR": "honor",
"TOS": "tos",
})
@patch.dict(settings.FEATURES, {"ENABLE_MKTG_SITE": True})
def test_registration_separate_terms_of_service_mktg_site_enabled(self):
# Honor code field should say ONLY honor code,
# not "terms of service and honor code"
self._assert_reg_field(
{"honor_code": "required", "terms_of_service": "required"},
{
"label": "I agree to the <a href=\"https://www.test.com/honor\">Honor Code</a>",
"name": "honor_code",
"default": False,
"type": "checkbox",
"required": True,
"placeholder": "",
"instructions": "",
"restrictions": {},
}
)
# Terms of service field should also be present
self._assert_reg_field(
{"honor_code": "required", "terms_of_service": "required"},
{
"label": "I agree to the <a href=\"https://www.test.com/tos\">Terms of Service</a>",
"name": "terms_of_service",
"default": False,
"type": "checkbox",
"required": True,
"placeholder": "",
"instructions": "",
"restrictions": {},
}
)
@override_settings(MKTG_URLS_LINK_MAP={"HONOR": "honor", "TOS": "tos"})
@patch.dict(settings.FEATURES, {"ENABLE_MKTG_SITE": False})
def test_registration_separate_terms_of_service_mktg_site_disabled(self):
# Honor code field should say ONLY honor code,
# not "terms of service and honor code"
self._assert_reg_field(
{"honor_code": "required", "terms_of_service": "required"},
{
"label": "I agree to the <a href=\"/honor\">Honor Code</a>",
"name": "honor_code",
"default": False,
"type": "checkbox",
"required": True,
"placeholder": "",
"instructions": "",
"restrictions": {},
}
)
# Terms of service field should also be present
self._assert_reg_field(
{"honor_code": "required", "terms_of_service": "required"},
{
"label": "I agree to the <a href=\"/tos\">Terms of Service</a>",
"name": "terms_of_service",
"default": False,
"type": "checkbox",
"required": True,
"placeholder": "",
"instructions": "",
"restrictions": {},
}
)
@override_settings(REGISTRATION_EXTRA_FIELDS={
"level_of_education": "optional",
"gender": "optional",
......
......@@ -136,12 +136,31 @@ class RegistrationView(APIView):
EXTRA_FIELDS = [
"city", "country", "level_of_education", "gender",
"year_of_birth", "mailing_address", "goals",
"honor_code",
"honor_code", "terms_of_service",
]
def _is_field_visible(self, field_name):
"""Check whether a field is visible based on Django settings. """
return self._extra_fields_setting.get(field_name) in ["required", "optional"]
def _is_field_required(self, field_name):
"""Check whether a field is required based on Django settings. """
return self._extra_fields_setting.get(field_name) == "required"
def __init__(self, *args, **kwargs):
super(RegistrationView, self).__init__(*args, **kwargs)
# Backwards compatibility: Honor code is required by default, unless
# explicitly set to "optional" in Django settings.
self._extra_fields_setting = copy.deepcopy(settings.REGISTRATION_EXTRA_FIELDS)
self._extra_fields_setting["honor_code"] = self._extra_fields_setting.get("honor_code", "required")
# Check that the setting is configured correctly
for field_name in self.EXTRA_FIELDS:
if self._extra_fields_setting.get(field_name, "hidden") not in ["required", "optional", "hidden"]:
msg = u"Setting REGISTRATION_EXTRA_FIELDS values must be either required, optional, or hidden."
raise ImproperlyConfigured(msg)
# Map field names to the instance method used to add the field to the form
self.field_handlers = {}
for field_name in (self.DEFAULT_FIELDS + self.EXTRA_FIELDS):
......@@ -175,22 +194,14 @@ class RegistrationView(APIView):
for field_name in self.DEFAULT_FIELDS:
self.field_handlers[field_name](form_desc, required=True)
# Backwards compatibility: Honor code is required by default, unless
# explicitly set to "optional" in Django settings.
extra_fields_setting = copy.deepcopy(settings.REGISTRATION_EXTRA_FIELDS)
extra_fields_setting["honor_code"] = extra_fields_setting.get("honor_code", "required")
# Extra fields configured in Django settings
# may be required, optional, or hidden
for field_name in self.EXTRA_FIELDS:
field_setting = extra_fields_setting.get(field_name, "hidden")
handler = self.field_handlers[field_name]
if field_setting in ["required", "optional"]:
handler(form_desc, required=(field_setting == "required"))
elif field_setting != "hidden":
msg = u"Setting REGISTRATION_EXTRA_FIELDS values must be either required, optional, or hidden."
raise ImproperlyConfigured(msg)
if self._is_field_visible(field_name):
self.field_handlers[field_name](
form_desc,
required=self._is_field_required(field_name)
)
return HttpResponse(form_desc.to_json(), content_type="application/json")
......@@ -342,8 +353,14 @@ class RegistrationView(APIView):
)
def _add_honor_code_field(self, form_desc, required=True):
# Translators: This is a legal document users must agree to in order to register a new account.
terms_text = _(u"Terms of Service and Honor Code")
# Separate terms of service and honor code checkboxes
if self._is_field_visible("terms_of_service"):
terms_text = _(u"Honor Code")
# Combine terms of service and honor code checkboxes
else:
# Translators: This is a legal document users must agree to in order to register a new account.
terms_text = _(u"Terms of Service and Honor Code")
# Translators: "Terms of service" is a legal document users must agree to in order to register a new account.
label = _(
......@@ -355,10 +372,6 @@ class RegistrationView(APIView):
)
)
# TODO: Open source installations may need
# separate checkboxes for terms or service or privacy
# policies. Instead of hard-coding this, we should create a more flexible
# mechanism for configuring which fields appear on the registration form.
form_desc.add_field(
"honor_code",
label=label,
......@@ -367,6 +380,28 @@ class RegistrationView(APIView):
required=required,
)
def _add_terms_of_service_field(self, form_desc, required=True):
# Translators: This is a legal document users must agree to in order to register a new account.
terms_text = _(u"Terms of Service")
# Translators: "Terms of service" is a legal document users must agree to in order to register a new account.
label = _(
u"I agree to the {terms_of_service}"
).format(
terms_of_service=u"<a href=\"{url}\">{terms_text}</a>".format(
url=marketing_link("TOS"),
terms_text=terms_text
)
)
form_desc.add_field(
"terms_of_service",
label=label,
field_type="checkbox",
default=False,
required=required,
)
def _options_with_default(self, options):
"""Include a default option as the first option. """
return (
......
......@@ -1536,6 +1536,7 @@ REGISTRATION_EXTRA_FIELDS = {
'mailing_address': 'optional',
'goals': 'optional',
'honor_code': 'required',
'terms_of_service': 'hidden',
'city': 'hidden',
'country': 'hidden',
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment