From b1c7cdf415459fbe38be39747fbdd506a160fecc Mon Sep 17 00:00:00 2001 From: Bessie Steinberg Date: Fri, 18 Aug 2017 13:25:05 -0400 Subject: [PATCH] Add profession & specialty fields to register page The site configurations can now set 'Profession' and 'Specialty' as fields on the registration page. The list of potential professions and specialties to choice from can also be set from the site configurations by setting 'PROFESSION_OPTIONS' and 'SPECIALTY_OPTIONS'. WL-1098 --- .../djangoapps/user_api/accounts/__init__.py | 4 + openedx/core/djangoapps/user_api/api.py | 76 ++++++++++++ .../djangoapps/user_api/tests/test_views.py | 109 ++++++++++++++++++ 3 files changed, 189 insertions(+) diff --git a/openedx/core/djangoapps/user_api/accounts/__init__.py b/openedx/core/djangoapps/user_api/accounts/__init__.py index 0710536452..aee873f651 100644 --- a/openedx/core/djangoapps/user_api/accounts/__init__.py +++ b/openedx/core/djangoapps/user_api/accounts/__init__.py @@ -84,6 +84,10 @@ PASSWORD_CANT_EQUAL_USERNAME_MSG = _(u"Password cannot be the same as the userna REQUIRED_FIELD_NAME_MSG = _(u"Enter your full name.") REQUIRED_FIELD_CONFIRM_EMAIL_MSG = _(u"The email addresses do not match.") REQUIRED_FIELD_COUNTRY_MSG = _(u"Select your country or region of residence.") +REQUIRED_FIELD_PROFESSION_SELECT_MSG = _(u"Select your profession.") +REQUIRED_FIELD_SPECIALTY_SELECT_MSG = _(u"Select your specialty.") +REQUIRED_FIELD_PROFESSION_TEXT_MSG = _(u"Enter your profession.") +REQUIRED_FIELD_SPECIALTY_TEXT_MSG = _(u"Enter your specialty.") REQUIRED_FIELD_CITY_MSG = _(u"Enter your city.") REQUIRED_FIELD_GOALS_MSG = _(u"Tell us your goals.") REQUIRED_FIELD_LEVEL_OF_EDUCATION_MSG = _(u"Select the highest level of education you have completed.") diff --git a/openedx/core/djangoapps/user_api/api.py b/openedx/core/djangoapps/user_api/api.py index 4275b7739b..c3ad3eda25 100644 --- a/openedx/core/djangoapps/user_api/api.py +++ b/openedx/core/djangoapps/user_api/api.py @@ -148,6 +148,8 @@ class RegistrationFormFactory(object): "goals", "honor_code", "terms_of_service", + "profession", + "specialty", ] def _is_field_visible(self, field_name): @@ -472,6 +474,80 @@ class RegistrationFormFactory(object): required=required ) + def _add_field_with_configurable_select_options(self, field_name, field_label, form_desc, required=False): + """Add a field to a form description. + If select options are given for this field, it will be a select type + otherwise it will be a text type. + + Arguments: + field_name: name of field + field_label: label for the field + form_desc: A form description + + Keyword Arguments: + required (bool): Whether this field is required; defaults to False + + """ + + extra_field_options = configuration_helpers.get_value('EXTRA_FIELD_OPTIONS') + if extra_field_options is None or extra_field_options.get(field_name) is None: + field_type = "text" + include_default_option = False + options = None + error_msg = '' + exec("error_msg = accounts.REQUIRED_FIELD_%s_TEXT_MSG" % (field_name.upper())) + else: + field_type = "select" + include_default_option = True + field_options = extra_field_options.get(field_name) + options = [(unicode(option.lower()), option) for option in field_options] + error_msg = '' + exec("error_msg = accounts.REQUIRED_FIELD_%s_SELECT_MSG" % (field_name.upper())) + + form_desc.add_field( + field_name, + label=field_label, + field_type=field_type, + options=options, + include_default_option=include_default_option, + required=required, + error_messages={ + "required": error_msg + } + ) + + def _add_profession_field(self, form_desc, required=False): + """Add a profession field to a form description. + + Arguments: + form_desc: A form description + + Keyword Arguments: + required (bool): Whether this field is required; defaults to False + + """ + # Translators: This label appears above a dropdown menu on the registration + # form used to select the user's profession + profession_label = _("Profession") + + self._add_field_with_configurable_select_options('profession', profession_label, form_desc, required=required) + + def _add_specialty_field(self, form_desc, required=False): + """Add a specialty field to a form description. + + Arguments: + form_desc: A form description + + Keyword Arguments: + required (bool): Whether this field is required; defaults to False + + """ + # Translators: This label appears above a dropdown menu on the registration + # form used to select the user's specialty + specialty_label = _("Specialty") + + self._add_field_with_configurable_select_options('specialty', specialty_label, form_desc, required=required) + def _add_mailing_address_field(self, form_desc, required=True): """Add a mailing address field to a form description. Arguments: diff --git a/openedx/core/djangoapps/user_api/tests/test_views.py b/openedx/core/djangoapps/user_api/tests/test_views.py index 4014bc088e..8bfd5f7f54 100644 --- a/openedx/core/djangoapps/user_api/tests/test_views.py +++ b/openedx/core/djangoapps/user_api/tests/test_views.py @@ -22,6 +22,7 @@ from django_comment_common import models from openedx.core.djangoapps.site_configuration.helpers import get_value from openedx.core.lib.api.test_utils import ApiTestCase, TEST_API_KEY from openedx.core.lib.time_zone_utils import get_display_time_zone +from openedx.core.djangoapps.site_configuration.tests.test_util import with_site_configuration from openedx.core.djangolib.testing.utils import CacheIsolationTestCase, skip_unless_lms from student.tests.factories import UserFactory from third_party_auth.tests.testutil import simulate_running_pipeline, ThirdPartyAuthTestMixin @@ -923,6 +924,52 @@ class RegistrationViewTest(ThirdPartyAuthTestMixin, UserAPITestCase): CITY = "Springfield" COUNTRY = "us" GOALS = "Learn all the things!" + PROFESSION_OPTIONS = [ + { + "name": u'--', + "value": u'', + "default": True + + }, + { + "value": u'software engineer', + "name": u'Software Engineer', + "default": False + }, + { + "value": u'teacher', + "name": u'Teacher', + "default": False + }, + { + "value": u'other', + "name": u'Other', + "default": False + } + ] + SPECIALTY_OPTIONS = [ + { + "name": u'--', + "value": u'', + "default": True + + }, + { + "value": "aerospace", + "name": "Aerospace", + "default": False + }, + { + "value": u'early education', + "name": u'Early Education', + "default": False + }, + { + "value": u'n/a', + "name": u'N/A', + "default": False + } + ] def setUp(self): super(RegistrationViewTest, self).setUp() @@ -1299,6 +1346,66 @@ class RegistrationViewTest(ThirdPartyAuthTestMixin, UserAPITestCase): } ) + def test_register_form_profession_without_profession_options(self): + self._assert_reg_field( + {"profession": "required"}, + { + "name": "profession", + "type": "text", + "required": True, + "label": "Profession", + "errorMessages": { + "required": "Enter your profession." + } + } + ) + + @with_site_configuration(configuration={"EXTRA_FIELD_OPTIONS": {"profession": ["Software Engineer", "Teacher", "Other"]}}) + def test_register_form_profession_with_profession_options(self): + self._assert_reg_field( + {"profession": "required"}, + { + "name": "profession", + "type": "select", + "required": True, + "label": "Profession", + "options": self.PROFESSION_OPTIONS, + "errorMessages": { + "required": "Select your profession." + }, + } + ) + + def test_register_form_specialty_without_specialty_options(self): + self._assert_reg_field( + {"specialty": "required"}, + { + "name": "specialty", + "type": "text", + "required": True, + "label": "Specialty", + "errorMessages": { + "required": "Enter your specialty." + } + } + ) + + @with_site_configuration(configuration={"EXTRA_FIELD_OPTIONS": {"specialty": ["Aerospace", "Early Education", "N/A"]}}) + def test_register_form_specialty_with_specialty_options(self): + self._assert_reg_field( + {"specialty": "required"}, + { + "name": "specialty", + "type": "select", + "required": True, + "label": "Specialty", + "options": self.SPECIALTY_OPTIONS, + "errorMessages": { + "required": "Select your specialty." + }, + } + ) + def test_registration_form_mailing_address(self): self._assert_reg_field( {"mailing_address": "optional"}, @@ -1618,6 +1725,8 @@ class RegistrationViewTest(ThirdPartyAuthTestMixin, UserAPITestCase): "goals", "honor_code", "terms_of_service", + "specialty", + "profession", ], ) def test_field_order_override(self):