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):