diff --git a/.env b/.env index 6a55858e0..6455153c1 100644 --- a/.env +++ b/.env @@ -2,10 +2,8 @@ ACCESS_TOKEN_COOKIE_NAME='' BASE_URL='' CREDENTIALS_BASE_URL='' CSRF_TOKEN_API_PATH='' -DEMOGRAPHICS_BASE_URL='' DISCOVERY_API_BASE_URL='' ECOMMERCE_BASE_URL='' -ENABLE_DEMOGRAPHICS_COLLECTION='' FAVICON_URL='' LANGUAGE_PREFERENCE_COOKIE_NAME='' LMS_BASE_URL='' diff --git a/.env.development b/.env.development index 8800ad579..a3d742a50 100644 --- a/.env.development +++ b/.env.development @@ -2,10 +2,8 @@ ACCESS_TOKEN_COOKIE_NAME='edx-jwt-cookie-header-payload' BASE_URL='localhost:1997' CREDENTIALS_BASE_URL='http://localhost:18150' CSRF_TOKEN_API_PATH='/csrf/api/v1/token' -DEMOGRAPHICS_BASE_URL='http://localhost:18360' DISCOVERY_API_BASE_URL='' ECOMMERCE_BASE_URL='http://localhost:18130' -ENABLE_DEMOGRAPHICS_COLLECTION='' FAVICON_URL=https://edx-cdn.org/v3/default/favicon.ico LANGUAGE_PREFERENCE_COOKIE_NAME='openedx-language-preference' LMS_BASE_URL='http://localhost:18000' diff --git a/.env.test b/.env.test index 9d10a9737..b9078fc77 100644 --- a/.env.test +++ b/.env.test @@ -2,10 +2,8 @@ ACCESS_TOKEN_COOKIE_NAME='edx-jwt-cookie-header-payload' BASE_URL='localhost:1997' CREDENTIALS_BASE_URL='http://localhost:18150' CSRF_TOKEN_API_PATH='/csrf/api/v1/token' -DEMOGRAPHICS_BASE_URL='http://localhost:18360' DISCOVERY_API_BASE_URL='' ECOMMERCE_BASE_URL='http://localhost:18130' -ENABLE_DEMOGRAPHICS_COLLECTION='' FAVICON_URL=https://edx-cdn.org/v3/default/favicon.ico LANGUAGE_PREFERENCE_COOKIE_NAME='openedx-language-preference' LMS_BASE_URL='http://localhost:18000' diff --git a/README.rst b/README.rst index 633bf982d..60d6448d9 100644 --- a/README.rst +++ b/README.rst @@ -16,9 +16,6 @@ What is the domain of this MFE? In this MFE: Private user settings UIs. Public facing profile is in a `separate MFE (Profile) `_ - Account settings page - -- Demographics collection - - IDV (Identity Verification) *************** @@ -99,23 +96,6 @@ Example: ``'false'`` | ``''`` (empty strings are true) Enable the account deletion option, defaults to true. To disable account deletion set ``ENABLE_ACCOUNT_DELETION`` to ``'false'`` (string), otherwise it will default to true. -edX-specific Environment Variables -================================== - -Furthermore, there are several edX-specific environment variables that enable integrations with closed-source services private to the edX organization, and are unsupported in Open edX. Enabling these environment variables will result in undefined behavior in Open edX installations: - -``ENABLE_DEMOGRAPHICS_COLLECTION`` - -Example: ``true`` | ``''`` (empty strings are falsy) - -Enables support for a section of the account settings page where a user can enter demographics information. Integrates with a private demographics service and is only used by edx.org. - -``DEMOGRAPHICS_BASE_URL`` - -Example: ``https://demographics.example.com`` - -Required only if ``ENABLE_DEMOGRAPHICS_COLLECTION`` is true. The fully-qualified URL to the private demographics service in the target environment. - Example build syntax with a single environment variable: .. code:: bash @@ -160,7 +140,6 @@ Development Roadmap We don't have anything planned for the core of the MFE (the account settings page) - this MFE is currently in maintenance mode. There may be a replacement for IDV coming down the pipe, so that may be DEPRed. -In the future, it's possible that demographics could be modeled as a plugin rather than being hard-coded into this MFE. License ======= diff --git a/src/account-settings/AccountSettingsPage.jsx b/src/account-settings/AccountSettingsPage.jsx index 8a6e54d05..6c2e336d8 100644 --- a/src/account-settings/AccountSettingsPage.jsx +++ b/src/account-settings/AccountSettingsPage.jsx @@ -49,7 +49,6 @@ import { getStatesList, } from './data/constants'; import { fetchSiteLanguages } from './site-language'; -import DemographicsSection from './demographics/DemographicsSection'; import { fetchCourseList } from '../notification-preferences/data/thunks'; import { withLocation, withNavigate } from './hoc'; @@ -65,7 +64,6 @@ class AccountSettingsPage extends React.Component { this.navLinkRefs = { '#basic-information': React.createRef(), '#profile-information': React.createRef(), - '#demographics-information': React.createRef(), '#social-media': React.createRef(), '#site-preferences': React.createRef(), '#linked-accounts': React.createRef(), @@ -460,16 +458,6 @@ class AccountSettingsPage extends React.Component { ); } - renderDemographicsSection() { - // check the result of an LMS API call to determine if we should render the DemographicsSection component - if (this.props.formValues.shouldDisplayDemographicsSection) { - return ( - - ); - } - return null; - } - renderContent() { const editableFieldProps = { onChange: this.handleEditableFieldChange, @@ -718,7 +706,6 @@ class AccountSettingsPage extends React.Component { {...editableFieldProps} /> - {getConfig().ENABLE_DEMOGRAPHICS_COLLECTION && this.renderDemographicsSection()}

{this.props.intl.formatMessage(messages['account.settings.section.social.media'])} @@ -844,9 +831,7 @@ class AccountSettingsPage extends React.Component {
- +
{loading ? this.renderLoading() : null} @@ -888,7 +873,6 @@ AccountSettingsPage.propTypes = { social_link_twitter: PropTypes.string, time_zone: PropTypes.string, state: PropTypes.string, - shouldDisplayDemographicsSection: PropTypes.bool, useVerifiedNameForCerts: PropTypes.bool.isRequired, verified_name: PropTypes.string, }).isRequired, diff --git a/src/account-settings/AccountSettingsPage.messages.jsx b/src/account-settings/AccountSettingsPage.messages.jsx index 7ad30e8ac..618f57d94 100644 --- a/src/account-settings/AccountSettingsPage.messages.jsx +++ b/src/account-settings/AccountSettingsPage.messages.jsx @@ -46,11 +46,6 @@ const messages = defineMessages({ defaultMessage: 'Profile Information', description: 'The profile information section heading.', }, - 'account.settings.section.demographics.information': { - id: 'account.settings.section.demographics.information', - defaultMessage: 'Optional Information', - description: 'The optional information section heading.', - }, 'account.settings.section.site.preferences': { id: 'account.settings.section.site.preferences', defaultMessage: 'Site Preferences', diff --git a/src/account-settings/JumpNav.jsx b/src/account-settings/JumpNav.jsx index 89aceba97..7251fcdae 100644 --- a/src/account-settings/JumpNav.jsx +++ b/src/account-settings/JumpNav.jsx @@ -3,7 +3,6 @@ import { injectIntl, intlShape } from '@edx/frontend-platform/i18n'; import { breakpoints, useWindowSize, Icon } from '@openedx/paragon'; import { OpenInNew } from '@openedx/paragon/icons'; import classNames from 'classnames'; -import PropTypes from 'prop-types'; import React from 'react'; import { useSelector } from 'react-redux'; import { NavHashLink } from 'react-router-hash-link'; @@ -14,7 +13,6 @@ import { selectShowPreferences } from '../notification-preferences/data/selector const JumpNav = ({ intl, - displayDemographicsLink, }) => { const stickToTop = useWindowSize().width > breakpoints.small.minWidth; const showPreferences = useSelector(selectShowPreferences()); @@ -25,7 +23,6 @@ const JumpNav = ({ items={[ 'basic-information', 'profile-information', - 'demographics-information', 'social-media', 'site-preferences', 'linked-accounts', @@ -44,14 +41,6 @@ const JumpNav = ({ {intl.formatMessage(messages['account.settings.section.profile.information'])} - {getConfig().ENABLE_DEMOGRAPHICS_COLLECTION && displayDemographicsLink - && ( -
  • - - {intl.formatMessage(messages['account.settings.section.demographics.information'])} - -
  • - )}
  • {intl.formatMessage(messages['account.settings.section.social.media'])} @@ -97,7 +86,6 @@ const JumpNav = ({ JumpNav.propTypes = { intl: intlShape.isRequired, - displayDemographicsLink: PropTypes.bool.isRequired, }; export default injectIntl(JumpNav); diff --git a/src/account-settings/data/selectors.js b/src/account-settings/data/selectors.js index 7650aa01e..1e6eb2497 100644 --- a/src/account-settings/data/selectors.js +++ b/src/account-settings/data/selectors.js @@ -298,21 +298,6 @@ export const certPreferenceSelector = createSelector( }), ); -export const demographicsSectionSelector = createSelector( - formValuesSelector, - draftsSelector, - errorSelector, - ( - formValues, - drafts, - errors, - ) => ({ - formValues, - drafts, - formErrors: errors, - }), -); - export const nameChangeSelector = createSelector( accountSettingsSelector, formValuesSelector, diff --git a/src/account-settings/data/service.js b/src/account-settings/data/service.js index d2f2e6118..10152c85c 100644 --- a/src/account-settings/data/service.js +++ b/src/account-settings/data/service.js @@ -1,15 +1,12 @@ import { getConfig } from '@edx/frontend-platform'; import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth'; import pick from 'lodash.pick'; -import pickBy from 'lodash.pickby'; import omit from 'lodash.omit'; import isEmpty from 'lodash.isempty'; import { handleRequestError, unpackFieldErrors } from './utils'; import { getThirdPartyAuthProviders } from '../third-party-auth'; import { postVerifiedNameConfig } from '../certificate-preference/data/service'; -import { getDemographics, getDemographicsOptions, patchDemographics } from '../demographics/data/service'; -import { DEMOGRAPHICS_FIELDS } from '../demographics/data/utils'; const SOCIAL_PLATFORMS = [ { id: 'twitter', key: 'social_link_twitter' }, @@ -154,28 +151,6 @@ export async function getProfileDataManager(username, userRoles) { return null; } -/** - * A function to determine if the Demographics questions should be displayed to the user. For the - * MVP release of Demographics we are limiting the Demographics question visibility only to - * MicroBachelors learners. - */ -export async function shouldDisplayDemographicsQuestions() { - const requestUrl = `${getConfig().LMS_BASE_URL}/api/demographics/v1/demographics/status/`; - let data = {}; - - try { - ({ data } = await getAuthenticatedHttpClient().get(requestUrl)); - if (data.display) { - return data.display; - } - } catch (error) { - // if there was an error then we just hide the section - return false; - } - - return false; -} - export async function getVerifiedName() { let data; const client = getAuthenticatedHttpClient(); @@ -212,28 +187,22 @@ export async function postVerifiedName(data) { } /** - * A single function to GET everything considered a setting. - * Currently encapsulates Account, Preferences, ThirdPartyAuth, and Demographics + * A single function to GET everything considered a setting. Currently encapsulates Account, Preferences, and + * ThirdPartyAuth. */ -export async function getSettings(username, userRoles, userId) { +export async function getSettings(username, userRoles) { const [ account, preferences, thirdPartyAuthProviders, profileDataManager, timeZones, - shouldDisplayDemographicsQuestionsResponse, - demographics, - demographicsOptions, ] = await Promise.all([ getAccount(username), getPreferences(username), getThirdPartyAuthProviders(), getProfileDataManager(username, userRoles), getTimeZones(), - getConfig().ENABLE_DEMOGRAPHICS_COLLECTION && shouldDisplayDemographicsQuestions(), - getConfig().ENABLE_DEMOGRAPHICS_COLLECTION && getDemographics(userId), - getConfig().ENABLE_DEMOGRAPHICS_COLLECTION && getDemographicsOptions(), ]); return { @@ -242,9 +211,6 @@ export async function getSettings(username, userRoles, userId) { thirdPartyAuthProviders, profileDataManager, timeZones, - shouldDisplayDemographicsSection: shouldDisplayDemographicsQuestionsResponse, - ...demographics, - demographicsOptions, }; } @@ -252,22 +218,18 @@ export async function getSettings(username, userRoles, userId) { * A single function to PATCH everything considered a setting. * Currently encapsulates Account, Preferences, ThirdPartyAuth */ -export async function patchSettings(username, commitValues, userId) { +export async function patchSettings(username, commitValues) { // Note: time_zone exists in the return value from user/v1/accounts // but it is always null and won't update. It also exists in // user/v1/preferences where it does update. This is the one we use. const preferenceKeys = ['time_zone']; - const demographicsKeys = DEMOGRAPHICS_FIELDS; const certificateKeys = ['useVerifiedNameForCerts']; - const isDemographicsKey = (value, key) => key.includes('demographics'); const accountCommitValues = omit( commitValues, preferenceKeys, - demographicsKeys, certificateKeys, ); const preferenceCommitValues = pick(commitValues, preferenceKeys); - const demographicsCommitValues = pickBy(commitValues, isDemographicsKey); const certCommitValues = pick(commitValues, certificateKeys); const patchRequests = []; @@ -277,9 +239,6 @@ export async function patchSettings(username, commitValues, userId) { if (!isEmpty(preferenceCommitValues)) { patchRequests.push(patchPreferences(username, preferenceCommitValues)); } - if (!isEmpty(demographicsCommitValues)) { - patchRequests.push(patchDemographics(userId, demographicsCommitValues)); - } if (!isEmpty(certCommitValues)) { patchRequests.push(postVerifiedNameConfig(username, certCommitValues)); } diff --git a/src/account-settings/demographics/Checkboxes.jsx b/src/account-settings/demographics/Checkboxes.jsx deleted file mode 100644 index a7cbb8b90..000000000 --- a/src/account-settings/demographics/Checkboxes.jsx +++ /dev/null @@ -1,80 +0,0 @@ -import React, { useEffect, useState } from 'react'; -import PropTypes from 'prop-types'; -import { Form } from '@openedx/paragon'; -import { DECLINED } from '../data/constants'; - -const Checkboxes = (props) => { - const { - id, - options, - values, - onChange, - } = props; - - const [selected, setSelected] = useState(values); - useEffect(() => { - onChange(id, selected); - }, [id, onChange, selected]); - - const handleToggle = (value, option) => { - // If the user checked 'declined', uncheck all other options - if (value && option === DECLINED) { - setSelected([DECLINED]); - return; - } - - // If option checked, make sure this option is in `selected` (and remove 'declined') - if (value && !selected.includes(option)) { - const newSelected = selected.filter(i => i !== DECLINED).concat(option); - setSelected(newSelected); - } - - // If unchecked, make sure this option is NOT in `selected` - if (!value) { - setSelected(selected.filter(i => i !== option)); - } - }; - - const renderCheckboxes = () => options.map((option, index) => { - const isFirst = index === 0; - const isChecked = selected.includes(option.value); - return ( -
    - handleToggle(event.target.checked, option.value)} - > - {option.label} - -
    - ); - }); - - return ( -
    - {renderCheckboxes()} -
    - ); -}; - -Checkboxes.propTypes = { - id: PropTypes.string.isRequired, - options: PropTypes.arrayOf(PropTypes.shape({ - value: PropTypes.string, - label: PropTypes.string, - })), - values: PropTypes.arrayOf(PropTypes.string), - onChange: PropTypes.func.isRequired, -}; - -Checkboxes.defaultProps = { - options: [], - values: [], -}; - -export default Checkboxes; diff --git a/src/account-settings/demographics/DemographicsSection.jsx b/src/account-settings/demographics/DemographicsSection.jsx deleted file mode 100644 index e22ef9248..000000000 --- a/src/account-settings/demographics/DemographicsSection.jsx +++ /dev/null @@ -1,357 +0,0 @@ -import { getConfig } from '@edx/frontend-platform'; -import { - FormattedMessage, - injectIntl, - intlShape, -} from '@edx/frontend-platform/i18n'; - -import { Hyperlink, Form } from '@openedx/paragon'; -import PropTypes from 'prop-types'; -import React from 'react'; -import { connect } from 'react-redux'; -import get from 'lodash.get'; -import isEmpty from 'lodash.isempty'; -import memoize from 'memoize-one'; -import { demographicsSectionSelector } from '../data/selectors'; -import EditableSelectField from '../EditableSelectField'; -import Checkboxes from './Checkboxes'; -import Alert from '../Alert'; -import { saveMultipleSettings, updateDraft } from '../data/actions'; -import { - OTHER, - SELF_DESCRIBE, -} from '../data/constants'; -import messages from './DemographicsSection.messages'; - -class DemographicsSection extends React.Component { - // We check the `demographicsOptions` prop to see if it is empty before we attempt to extract and - // format the available options for each question from the API response. - getApiOptions = memoize((demographicsOptions) => (this.hasRetrievedDemographicsOptions() && { - demographicsGenderOptions: this.addDefaultOption('account.settings.field.demographics.gender.options.empty') - .concat(demographicsOptions.actions.POST.gender.choices.map(key => ({ - value: key.value, - label: key.display_name, - }))), - /* Ethnicity options don't need the blank/default option */ - demographicsEthnicityOptions: demographicsOptions.actions.POST.user_ethnicity.child.children.ethnicity.choices.map( - key => ({ - value: key.value, - label: key.display_name, - }), - ), - demographicsIncomeOptions: this.addDefaultOption('account.settings.field.demographics.income.options.empty') - .concat(demographicsOptions.actions.POST.income.choices.map(key => ({ - value: key.value, - label: key.display_name, - }))), - demographicsMilitaryHistoryOptions: this.addDefaultOption('account.settings.field.demographics.military_history.options.empty') - .concat(demographicsOptions.actions.POST.military_history.choices.map(key => ({ - value: key.value, - label: key.display_name, - }))), - demographicsEducationLevelOptions: this.addDefaultOption('account.settings.field.demographics.education_level.options.empty') - .concat(demographicsOptions.actions.POST.learner_education_level.choices.map(key => ({ - value: key.value, - label: key.display_name, - }))), - demographicsWorkStatusOptions: this.addDefaultOption('account.settings.field.demographics.work_status.options.empty') - .concat(demographicsOptions.actions.POST.work_status.choices.map(key => ({ - value: key.value, - label: key.display_name, - }))), - demographicsWorkSectorOptions: this.addDefaultOption('account.settings.field.demographics.work_sector.options.empty') - .concat(demographicsOptions.actions.POST.current_work_sector.choices.map(key => ({ - value: key.value, - label: key.display_name, - }))), - })); - - ethnicityFieldDisplay = (demographicsEthnicityOptions) => { - let ethnicities = []; - if (get(this, 'props.formValues.demographics_user_ethnicity')) { - ethnicities = this.props.formValues.demographics_user_ethnicity; - } - return ethnicities.map((e) => { - const matchingOption = demographicsEthnicityOptions.filter(option => option.value === e)[0]; - return matchingOption && matchingOption.label; - }).join(', '); - }; - - handleEditableFieldChange = (name, value) => { - this.props.updateDraft(name, value); - }; - - handleSubmit = (formId) => { - // We have some custom fields in this section. Instead of relying on the - // submitted values, submit the values stored in 'drafts'. - const { drafts } = this.props; - const settingsArray = Object.entries(drafts).map(([field, value]) => ({ - formId: field, - commitValues: value, - })); - - this.props.saveMultipleSettings(settingsArray, formId); - }; - - /** - * Utility method that adds the specified message as a default option to the list of available - * choices. - * - * @param {*} messageId id of message matching desired default label text - */ - addDefaultOption(messageId) { - return [{ - value: '', - label: this.props.intl.formatMessage(messages[messageId]), - }]; - } - - /** - * Utility method that helps determine if we were able to retrieve the available options for - * the Demographics questions. Returns true if the `demographicsOptions` prop is _not_ empty, - * otherwise false. This prop being empty is indicative of a failure communicating with the - * Demographics IDA's API. - */ - hasRetrievedDemographicsOptions() { - return !isEmpty(this.props.formValues.demographicsOptions); - } - - /** - * If an error is encountered when trying to communicate with the Demographics IDA then we will - * display an Alert letting the user know that their info will not be displayed and temporarily - * cannot be updated. - */ - renderDemographicsServiceIssueWarning() { - if (!isEmpty(this.props.formErrors.demographicsError) - || !this.hasRetrievedDemographicsOptions()) { - return ( -
    - - - -
    - ); - } - return null; - } - - render() { - const editableFieldProps = { - onChange: this.handleEditableFieldChange, - onSubmit: this.handleSubmit, - }; - - const { - demographicsGenderOptions, - demographicsEthnicityOptions, - demographicsIncomeOptions, - demographicsMilitaryHistoryOptions, - demographicsEducationLevelOptions, - demographicsWorkStatusOptions, - demographicsWorkSectorOptions, - } = this.getApiOptions(this.props.formValues.demographicsOptions); - - const showSelfDescribe = this.props.formValues.demographics_gender === SELF_DESCRIBE; - const showWorkStatusDescribe = this.props.formValues.demographics_work_status === OTHER; - - return ( -
    -

    - {this.props.intl.formatMessage(messages['account.settings.section.demographics.information'])} -

    -

    - - {this.props.intl.formatMessage( - messages['account.settings.section.demographics.why'], - { - siteName: getConfig().SITE_NAME, - }, - )} - -

    - {this.renderDemographicsServiceIssueWarning()} - {/* - If the demographicsOptions props are empty then there is no need to display the fields as - the user will not have any choices available to select, nor will they be able to update - their answers. - */} - {this.hasRetrievedDemographicsOptions() && ( -
    - - {showSelfDescribe && ( - this.handleEditableFieldChange('demographics_gender_description', e.target.value)} - aria-label={this.props.intl.formatMessage(messages['account.settings.field.demographics.gender_description'])} - className="mt-1" - /> - )} - - - - - - - - {showWorkStatusDescribe && ( - this.handleEditableFieldChange('demographics_work_status_description', e.target.value)} - aria-label={this.props.intl.formatMessage(messages['account.settings.field.demographics.work_status_description'])} - className="mt-1" - /> - )} - - - -
    - )} -
    - ); - } -} - -DemographicsSection.propTypes = { - intl: intlShape.isRequired, - formValues: PropTypes.shape({ - demographics_gender: PropTypes.string, - demographics_user_ethnicity: PropTypes.shape([]), - demographics_income: PropTypes.string, - demographics_military_history: PropTypes.string, - demographics_learner_education_level: PropTypes.string, - demographics_parent_education_level: PropTypes.string, - demographics_work_status: PropTypes.string, - demographics_current_work_sector: PropTypes.string, - demographics_future_work_sector: PropTypes.string, - demographics_work_status_description: PropTypes.string, - demographics_gender_description: PropTypes.string, - demographicsOptions: PropTypes.shape({}), - }).isRequired, - drafts: PropTypes.shape({ - demographics_gender: PropTypes.string, - demographics_user_ethnicity: PropTypes.shape([]), - demographics_income: PropTypes.string, - demographics_military_history: PropTypes.string, - demographics_learner_education_level: PropTypes.string, - demographics_parent_education_level: PropTypes.string, - demographics_work_status: PropTypes.string, - demographics_current_work_sector: PropTypes.string, - demographics_future_work_sector: PropTypes.string, - demographics_work_status_description: PropTypes.string, - demographics_gender_description: PropTypes.string, - demographicsOptions: PropTypes.shape({}), - }).isRequired, - formErrors: PropTypes.shape({ - demographicsError: PropTypes.string, - }).isRequired, - forwardRef: PropTypes.func.isRequired, - updateDraft: PropTypes.func.isRequired, - saveMultipleSettings: PropTypes.func.isRequired, -}; - -export default connect(demographicsSectionSelector, { - saveMultipleSettings, - updateDraft, -})(injectIntl(DemographicsSection)); diff --git a/src/account-settings/demographics/DemographicsSection.messages.jsx b/src/account-settings/demographics/DemographicsSection.messages.jsx deleted file mode 100644 index 55117a1e6..000000000 --- a/src/account-settings/demographics/DemographicsSection.messages.jsx +++ /dev/null @@ -1,170 +0,0 @@ -import { defineMessages } from '@edx/frontend-platform/i18n'; - -const messages = defineMessages({ - /* Demographics section heading */ - 'account.settings.section.demographics.information': { - id: 'account.settings.section.demographics.information', - defaultMessage: 'Optional Information', - description: 'The optional information section heading.', - }, - /* Gender identity */ - 'account.settings.field.demographics.gender': { - id: 'account.settings.field.demographics.gender', - defaultMessage: 'Gender identity', - description: 'Label for account settings gender identity field.', - }, - 'account.settings.field.demographics.gender.empty': { - id: 'account.settings.field.demographics.gender.empty', - defaultMessage: 'Add gender identity', - description: 'Placeholder for empty account settings gender identity field.', - }, - 'account.settings.field.demographics.gender.options.empty': { - id: 'account.settings.field.demographics.gender.options.empty', - defaultMessage: 'Select a gender identity', - description: 'Placeholder for the gender identity options dropdown.', - }, - 'account.settings.field.demographics.gender_description': { - id: 'account.settings.field.demographics.gender_description', - defaultMessage: 'Gender identity description', - description: 'Label for account settings gender identity description field.', - }, - 'account.settings.field.demographics.gender_description.empty': { - id: 'account.settings.field.demographics.gender_description.empty', - defaultMessage: 'Enter description', - description: 'Placeholder for empty account settings gender identity field.', - }, - /* Ethnicity */ - 'account.settings.field.demographics.ethnicity': { - id: 'account.settings.field.demographics.ethnicity', - defaultMessage: 'Race/Ethnicity identity', - description: 'Label for account settings ethnic background field.', - }, - 'account.settings.field.demographics.ethnicity.empty': { - id: 'account.settings.field.demographics.ethnicity.empty', - defaultMessage: 'Add race/ethnicity identity', - description: 'Placeholder for empty account settings ethnic background field.', - }, - 'account.settings.field.demographics.ethnicity.options.empty': { - id: 'account.settings.field.demographics.ethnicity.options.empty', - defaultMessage: 'Select all that apply', // TODO: Is this the desired text? - description: 'Placeholder for the ethnic background options field.', - }, - /* Income */ - 'account.settings.field.demographics.income': { - id: 'account.settings.field.demographics.income', - defaultMessage: 'Family income', - description: 'Label for account settings household income field.', - }, - 'account.settings.field.demographics.income.empty': { - id: 'account.settings.field.demographics.income.empty', - defaultMessage: 'Add family income', - description: 'Placeholder for empty account settings household income field.', - }, - 'account.settings.field.demographics.income.options.empty': { - id: 'account.settings.field.demographics.income.options.empty', - defaultMessage: 'Select a family income range', - description: 'Placeholder for the household income dropdown.', - }, - /* Military history */ - 'account.settings.field.demographics.military_history': { - id: 'account.settings.field.demographics.military_history', - defaultMessage: 'U.S. Military status', - description: 'Label for account settings military history field.', - }, - 'account.settings.field.demographics.military_history.empty': { - id: 'account.settings.field.demographics.military_history.empty', - defaultMessage: 'Add military status', - description: 'Placeholder for empty account settings military history field.', - }, - 'account.settings.field.demographics.military_history.options.empty': { - id: 'account.settings.field.demographics.military_history.options.empty', - defaultMessage: 'Select military status', - description: 'Placeholder for the military history dropdown.', - }, - /* Learner and family education level */ - 'account.settings.field.demographics.learner_education_level': { - id: 'account.settings.field.demographics.learner_education_level', - defaultMessage: 'Your education level', - description: 'Label for account settings learner education level field.', - }, - 'account.settings.field.demographics.learner_education_level.empty': { - id: 'account.settings.field.demographics.learner_education_level.empty', - defaultMessage: 'Add education level', - description: 'Placeholder for empty account settings learner education level field.', - }, - 'account.settings.field.demographics.parent_education_level': { - id: 'account.settings.field.demographics.parent_education_level', - defaultMessage: 'Parents/Guardians education level', - description: 'Label for account settings parent education level field.', - }, - 'account.settings.field.demographics.parent_education_level.empty': { - id: 'account.settings.field.demographics.parent_education_level.empty', - defaultMessage: 'Add education level', - description: 'Placeholder for empty account settings parent education level field.', - }, - 'account.settings.field.demographics.education_level.options.empty': { - id: 'account.settings.field.demographics.education_level.options.empty', - defaultMessage: 'Select education level', - description: 'Placeholder for the education level options dropdown.', - }, - /* Work status */ - 'account.settings.field.demographics.work_status': { - id: 'account.settings.field.demographics.work_status', - defaultMessage: 'Employment status', - description: 'Label for account settings work status field.', - }, - 'account.settings.field.demographics.work_status.empty': { - id: 'account.settings.field.demographics.work_status.empty', - defaultMessage: 'Add employment status', - description: 'Placeholder for empty account settings work status field.', - }, - 'account.settings.field.demographics.work_status.options.empty': { - id: 'account.settings.field.demographics.work_status.options.empty', - defaultMessage: 'Select employment status', - description: 'Placeholder for the work status options dropdown.', - }, - 'account.settings.field.demographics.work_status_description': { - id: 'account.settings.field.demographics.work_status_description', - defaultMessage: 'Employment status description', - description: 'Label for account settings work status description field.', - }, - 'account.settings.field.demographics.work_status_description.empty': { - id: 'account.settings.field.demographics.work_status_description.empty', - defaultMessage: 'Enter description', - description: 'Placeholder for empty account settings work status description field.', - }, - /* Work sector */ - 'account.settings.field.demographics.current_work_sector': { - id: 'account.settings.field.demographics.current_work_sector', - defaultMessage: 'Current work industry', - description: 'Label for account settings current work sector field.', - }, - 'account.settings.field.demographics.current_work_sector.empty': { - id: 'account.settings.field.demographics.current_work_sector.empty', - defaultMessage: 'Add work industry', - description: 'Placeholder for empty account settings current work sector field.', - }, - 'account.settings.field.demographics.future_work_sector': { - id: 'account.settings.field.demographics.future_work_sector', - defaultMessage: 'Future work industry', - description: 'Label for account settings future work sector field.', - }, - 'account.settings.field.demographics.future_work_sector.empty': { - id: 'account.settings.field.demographics.future_work_sector.empty', - defaultMessage: 'Add work industry', - description: 'Placeholder for empty account settings future work sector field.', - }, - 'account.settings.field.demographics.work_sector.options.empty': { - id: 'account.settings.field.demographics.work_sector.options.empty', - defaultMessage: 'Select work industry', - description: 'Placeholder for the work sector options dropdown.', - }, - /* Legal copy link text */ - 'account.settings.section.demographics.why': { - id: 'account.settings.section.demographics.why', - defaultMessage: 'Why does {siteName} collect this information?', - description: 'Link text for a link to external legal text', - }, -}); - -export default messages; diff --git a/src/account-settings/demographics/data/service.js b/src/account-settings/demographics/data/service.js deleted file mode 100644 index 0ce1d7113..000000000 --- a/src/account-settings/demographics/data/service.js +++ /dev/null @@ -1,140 +0,0 @@ -import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth'; -import { getConfig } from '@edx/frontend-platform'; -import get from 'lodash.get'; -import { convertData, TO, FROM } from './utils'; - -/** - * Utility method that attempts to extract errors from the response of a PATCH request in order to - * display a warning or otherwise meaningful message to the user. - * - * @param {Error} error - */ -export function createDemographicsError(error) { - const apiError = Object.create(error); - // If the error received has the `httpResponseData` field in it, then we should have reason to - // believe the Demographics service is alive and responding. Extract errors from fields where - // appropriate so we can display them to the user. - if (get(error, 'customAttributes.httpErrorResponseData')) { - apiError.fieldErrors = JSON.parse(error.customAttributes.httpErrorResponseData); - if (get(apiError, 'fieldErrors.gender_description')) { - // eslint-disable-next-line prefer-destructuring - apiError.fieldErrors.demographics_gender = apiError.fieldErrors.gender_description[0]; - delete apiError.fieldErrors.gender_description; - } else if (get(apiError, 'fieldErrors.work_status_description')) { - // eslint-disable-next-line prefer-destructuring - apiError.fieldErrors.demographics_work_status = apiError.fieldErrors.work_status_description[0]; - delete apiError.fieldErrors.work_status_description; - } - // Otherwise, when the service is down, the error response will not contain a - // `httpErrorResponseData` field. Add a generic 'demographicsError' field to the fieldErrors that - // will trigger showing an Alert to the user to them them know the update was unsuccessful. - } else { - apiError.fieldErrors = { - demographicsError: error.customAttributes.httpErrorType, - }; - } - - return apiError; -} - -/** - * post all of the data related to demographics. - * @param {Number} userId users are identified in the api by LMS id - * @param {Object} commitValues { demographics } - */ -export async function postDemographics(userId) { - const requestConfig = { headers: { 'Content-Type': 'application/json' } }; - const requestUrl = `${getConfig().DEMOGRAPHICS_BASE_URL}/demographics/api/v1/demographics/`; - const commitValues = { user: userId }; - let data = {}; - - ({ data } = await getAuthenticatedHttpClient() - .post(requestUrl, commitValues, requestConfig) - .catch((error) => { - const apiError = createDemographicsError(error); - throw apiError; - })); - - return convertData(data, FROM); -} - -/** - * get all data related to the demographics. - * @param {Number} userId users are identified in the api by LMS id - */ -export async function getDemographics(userId) { - const requestUrl = `${getConfig().DEMOGRAPHICS_BASE_URL}/demographics/api/v1/demographics/${userId}/`; - let data = {}; - - try { - ({ data } = await getAuthenticatedHttpClient() - .get(requestUrl)); - - data = convertData(data, FROM); - } catch (error) { - const apiError = Object.create(error); - // if the API called resulted in this user receiving a 404 then follow up with a POST call to - // try and create the demographics entity on the backend - if (apiError.customAttributes.httpErrorStatus) { - if (apiError.customAttributes.httpErrorStatus === 404) { - data = await postDemographics(userId); - } - } else { - data = { - user: userId, - demographics_gender: '', - demographics_gender_description: '', - demographics_income: '', - demographics_learner_education_level: '', - demographics_parent_education_level: '', - demographics_military_history: '', - demographics_work_status: '', - demographics_work_status_description: '', - demographics_current_work_sector: '', - demographics_future_work_sector: '', - demographics_user_ethnicity: [], - }; - } - } - - return data; -} - -/** - * patch all of the data related to demographics. - * @param {Number} userId users are identified in the api by LMS id - * @param {Object} commitValues { demographics } - */ -export async function patchDemographics(userId, commitValues) { - const requestUrl = `${getConfig().DEMOGRAPHICS_BASE_URL}/demographics/api/v1/demographics/${userId}/`; - const convertedCommitValues = convertData(commitValues, TO); - let data = {}; - - ({ data } = await getAuthenticatedHttpClient() - .patch(requestUrl, convertedCommitValues) - .catch((error) => { - const apiError = createDemographicsError(error); - throw apiError; - })); - - return convertData(data, FROM); -} - -/** - * retrieve the options for each field from the Demographics API - */ -export async function getDemographicsOptions() { - const requestUrl = `${getConfig().DEMOGRAPHICS_BASE_URL}/demographics/api/v1/demographics/`; - let data = {}; - - try { - ({ data } = await getAuthenticatedHttpClient().options(requestUrl)); - } catch (error) { - // We are catching and suppressing errors here on purpose. If an error occurs during the - // getDemographicsOptions call we will pass back an empty `data` object. Downstream we make - // the assumption that if the demographicsOptions object is empty that there was an issue or - // error communicating with the service/API. - } - - return data; -} diff --git a/src/account-settings/demographics/data/utils.js b/src/account-settings/demographics/data/utils.js deleted file mode 100644 index f5609f822..000000000 --- a/src/account-settings/demographics/data/utils.js +++ /dev/null @@ -1,63 +0,0 @@ -export const TO = 'to'; -export const FROM = 'from'; -export const DEMOGRAPHICS_FIELDS = [ - 'demographics_gender', - 'demographics_gender_description', - 'demographics_income', - 'demographics_learner_education_level', - 'demographics_parent_education_level', - 'demographics_military_history', - 'demographics_work_status', - 'demographics_work_status_description', - 'demographics_current_work_sector', - 'demographics_future_work_sector', - 'demographics_user_ethnicity', -]; - -// Frontend wants (example): -// demographics_user_ethnicity: ["asian", "white", "other"] -// -// Demographics wants (example): -// user_ethnicity: [ -// { ethnicity: "asian" }, -// { ethnicity: "white" }, -// { ethnicity: "other" } -// ] -function convertEthnicity(ethnicityData, direction) { - if (direction === FROM) { - return ethnicityData.map(e => e.ethnicity); - } - - if (direction === TO) { - return ethnicityData.map(e => ({ ethnicity: e })); - } - - return ethnicityData; -} - -// Handles conversion of data to/from Demographics IDA to/from format needed for -// frontend -// * handles ethnicity field -// * adds/removes 'demographics' to/from key -// * replace `null` with empty string or empty string with null -export function convertData(dataObject, direction) { - const converted = {}; - - Object.entries(dataObject).forEach(([key, value]) => { - let newValue = value; - - if (key.includes('ethnicity')) { - newValue = convertEthnicity(value, direction); - } - - if (direction === TO) { - converted[key.replace('demographics_', '')] = newValue || null; - } - - if (direction === FROM) { - converted[`demographics_${key}`] = newValue || ''; - } - }); - - return converted; -} diff --git a/src/account-settings/demographics/test/DemographicsSection.test.jsx b/src/account-settings/demographics/test/DemographicsSection.test.jsx deleted file mode 100644 index ba95cbef7..000000000 --- a/src/account-settings/demographics/test/DemographicsSection.test.jsx +++ /dev/null @@ -1,584 +0,0 @@ -/* eslint-disable no-import-assign */ -import * as auth from '@edx/frontend-platform/auth'; - -import { IntlProvider, injectIntl } from '@edx/frontend-platform/i18n'; - -import { Provider } from 'react-redux'; -import React from 'react'; -import configureStore from 'redux-mock-store'; -import renderer from 'react-test-renderer'; -import DemographicsSection from '../DemographicsSection'; - -jest.mock('@edx/frontend-platform/auth'); - -const IntlDemographicsSection = injectIntl(DemographicsSection); - -jest.mock('../../data/selectors', () => jest.fn().mockImplementation(() => ({ demographicsSectionSelector: () => ({}) }))); - -const mockStore = configureStore(); - -describe('DemographicsSection', () => { - let props = {}; - let store = {}; - - const reduxWrapper = children => ( - - {children} - - ); - - beforeEach(() => { - store = mockStore(); - props = { - updateDraft: jest.fn(), - formValues: { - demographics_gender: 'declined', - demographics_gender_description: '', - demographics_user_ethnicity: [], - demographics_income: 'declined', - demographics_military_history: 'declined', - demographics_learner_education_level: 'declined', - demographics_parent_education_level: 'declined', - demographics_work_status: 'declined', - demographics_work_status_description: '', - demographics_current_work_sector: 'declined', - demographics_future_work_sector: 'declined', - demographics_user: 1, - demographicsOptions: { - actions: { - POST: { - gender: { - choices: [ - { - value: 'woman', - display_name: 'Woman', - }, - { - value: 'man', - display_name: 'Man', - }, - { - value: 'non-binary', - display_name: 'Non-binary', - }, - { - value: 'self-describe', - display_name: 'Prefer to self describe', - }, - { - value: 'declined', - display_name: 'Prefer not to respond', - }, - ], - }, - income: { - choices: [ - { - value: 'less-than-10k', - display_name: 'Less than US $10,000', - }, - { - value: '10k-25k', - display_name: 'US $10,000 - $25,000', - }, - { - value: '25k-50k', - display_name: 'US $25,000 - $50,000', - }, - { - value: '50k-75k', - display_name: 'US $50,000 - $75,000', - }, - { - value: '75k-100k', - display_name: 'US $75,000 - $100,000', - }, - { - value: 'over-100k', - display_name: 'Over US $100,000', - }, - { - value: 'unsure', - display_name: "I don't know", - }, - { - value: 'declined', - display_name: 'Prefer not to respond', - }, - ], - }, - learner_education_level: { - choices: [ - { - value: 'no-high-school', - display_name: 'No High School', - }, - { - value: 'some-high-school', - display_name: 'Some High School', - }, - { - value: 'high-school-ged-equivalent', - display_name: 'High School diploma, GED, or equivalent', - }, - { - value: 'some-college', - display_name: 'Some college, but no degree', - }, - { - value: 'associates', - display_name: 'Associates degree', - }, - { - value: 'bachelors', - display_name: 'Bachelors degree', - }, - { - value: 'masters', - display_name: 'Masters degree', - }, - { - value: 'professional', - display_name: 'Professional degree', - }, - { - value: 'doctorate', - display_name: 'Doctorate degree', - }, - { - value: 'declined', - display_name: 'Prefer not to respond', - }, - ], - }, - parent_education_level: { - choices: [ - { - value: 'no-high-school', - display_name: 'No High School', - }, - { - value: 'some-high-school', - display_name: 'Some High School', - }, - { - value: 'high-school-ged-equivalent', - display_name: 'High School diploma, GED, or equivalent', - }, - { - value: 'some-college', - display_name: 'Some college, but no degree', - }, - { - value: 'associates', - display_name: 'Associates degree', - }, - { - value: 'bachelors', - display_name: 'Bachelors degree', - }, - { - value: 'masters', - display_name: 'Masters degree', - }, - { - value: 'professional', - display_name: 'Professional degree', - }, - { - value: 'doctorate', - display_name: 'Doctorate degree', - }, - { - value: 'declined', - display_name: 'Prefer not to respond', - }, - ], - }, - military_history: { - choices: [ - { - value: 'never-served', - display_name: 'Never served in the military', - }, - { - value: 'training', - display_name: 'Only on active duty for training', - }, - { - value: 'active', - display_name: 'Now on active duty', - }, - { - value: 'previously-active', - display_name: 'On active duty in the past, but not now', - }, - { - value: 'declined', - display_name: 'Prefer not to respond', - }, - ], - }, - work_status: { - choices: [ - { - value: 'full-time', - display_name: 'Employed, working full-time', - }, - { - value: 'part-time', - display_name: 'Employed, working part-time', - }, - { - value: 'self-employed', - display_name: 'Self-Employed', - }, - { - value: 'not-employed-looking', - display_name: 'Not employed, looking for work', - }, - { - value: 'not-employed-not-looking', - display_name: 'Not employed, not looking for work', - }, - { - value: 'unable', - display_name: 'Unable to work', - }, - { - value: 'retired', - display_name: 'Retired', - }, - { - value: 'other', - display_name: 'Other', - }, - { - value: 'declined', - display_name: 'Prefer not to respond', - }, - ], - }, - current_work_sector: { - choices: [ - { - value: 'accommodation-food', - display_name: 'Accommodation and Food Services', - }, - { - value: 'administrative-support-waste-remediation', - display_name: 'Administrative and Support and Waste Management and Remediation Services', - }, - { - value: 'agriculture-forestry-fishing-hunting', - display_name: 'Agriculture, Forestry, Fishing and Hunting', - }, - { - value: 'arts-entertainment-recreation', - display_name: 'Arts, Entertainment, and Recreation', - }, - { - value: 'construction', - display_name: 'Construction', - }, - { - value: 'educational', - display_name: 'Education Services', - }, - { - value: 'finance-insurance', - display_name: 'Finance and Insurance', - }, - { - value: 'healthcare-social', - display_name: 'Health Care and Social Assistance', - }, - { - value: 'information', - display_name: 'Information', - }, - { - value: 'management', - display_name: 'Management of Companies and Enterprises', - }, - { - value: 'manufacturing', - display_name: 'Manufacturing', - }, - { - value: 'mining-quarry-oil-gas', - display_name: 'Mining, Quarrying, and Oil and Gas Extraction', - }, - { - value: 'professional-scientific-technical', - display_name: 'Professional, Scientific, and Technical Services', - }, - { - value: 'public-admin', - display_name: 'Public Administration', - }, - { - value: 'real-estate', - display_name: 'Real Estate and Rental and Leasing', - }, - { - value: 'retail', - display_name: 'Retail Trade', - }, - { - value: 'transport-warehousing', - display_name: 'Transportation and Warehousing', - }, - { - value: 'utilities', - display_name: 'Utilities', - }, - { - value: 'trade', - display_name: 'Wholesale Trade', - }, - { - value: 'other', - display_name: 'Other', - }, - { - value: 'declined', - display_name: 'Prefer not to respond', - }, - ], - }, - future_work_sector: { - choices: [ - { - value: 'accommodation-food', - display_name: 'Accommodation and Food Services', - }, - { - value: 'administrative-support-waste-remediation', - display_name: 'Administrative and Support and Waste Management and Remediation Services', - }, - { - value: 'agriculture-forestry-fishing-hunting', - display_name: 'Agriculture, Forestry, Fishing and Hunting', - }, - { - value: 'arts-entertainment-recreation', - display_name: 'Arts, Entertainment, and Recreation', - }, - { - value: 'construction', - display_name: 'Construction', - }, - { - value: 'educational', - display_name: 'Education Services', - }, - { - value: 'finance-insurance', - display_name: 'Finance and Insurance', - }, - { - value: 'healthcare-social', - display_name: 'Health Care and Social Assistance', - }, - { - value: 'information', - display_name: 'Information', - }, - { - value: 'management', - display_name: 'Management of Companies and Enterprises', - }, - { - value: 'manufacturing', - display_name: 'Manufacturing', - }, - { - value: 'mining-quarry-oil-gas', - display_name: 'Mining, Quarrying, and Oil and Gas Extraction', - }, - { - value: 'professional-scientific-technical', - display_name: 'Professional, Scientific, and Technical Services', - }, - { - value: 'public-admin', - display_name: 'Public Administration', - }, - { - value: 'real-estate', - display_name: 'Real Estate and Rental and Leasing', - }, - { - value: 'retail', - display_name: 'Retail Trade', - }, - { - value: 'transport-warehousing', - display_name: 'Transportation and Warehousing', - }, - { - value: 'utilities', - display_name: 'Utilities', - }, - { - value: 'trade', - display_name: 'Wholesale Trade', - }, - { - value: 'other', - display_name: 'Other', - }, - { - value: 'declined', - display_name: 'Prefer not to respond', - }, - ], - }, - user_ethnicity: { - child: { - children: { - ethnicity: { - choices: [ - { - value: 'american-indian-or-alaska-native', - display_name: 'American Indian or Alaska Native', - }, - { - value: 'asian', - display_name: 'Asian', - }, - { - value: 'black-or-african-american', - display_name: 'Black or African American', - }, - { - value: 'hispanic-latin-spanish', - display_name: 'Hispanic, Latin, or Spanish origin', - }, - { - value: 'middle-eastern-or-north-african', - display_name: 'Middle Eastern or North African', - }, - { - value: 'native-hawaiian-or-pacific-islander', - display_name: 'Native Hawaiian or Other Pacific Islander', - }, - { - value: 'white', - display_name: 'White', - }, - { - value: 'other', - display_name: 'Some other race, ethnicity, or origin', - }, - { - value: 'declined', - display_name: 'Prefer not to respond', - }, - ], - }, - }, - }, - }, - }, - }, - }, - }, - formErrors: {}, - intl: {}, - forwardRef: () => {}, - drafts: {}, - }; - auth.getAuthenticatedHttpClient = jest.fn(() => ({ - patch: async () => ({ - data: { status: 200 }, - catch: () => {}, - }), - })); - auth.getAuthenticatedUser = jest.fn(() => ({ userId: 1 })); - }); - - it('should render', () => { - const wrapper = renderer.create(reduxWrapper()).toJSON(); - expect(wrapper).toMatchSnapshot(); - }); - - it('should render an Alert if an error occurs', () => { - props = { - ...props, - formErrors: { - demographicsError: 'api-error', - }, - }; - - const wrapper = renderer.create(reduxWrapper()).toJSON(); - expect(wrapper).toMatchSnapshot(); - }); - - it('should set user input correctly when user provides gender self-description', () => { - props = { - ...props, - formValues: { - ...props.formValues, - demographics_gender: 'self-describe', - demographics_gender_description: 'test', - }, - }; - - const wrapper = renderer.create(reduxWrapper()).toJSON(); - expect(wrapper).toMatchSnapshot(); - }); - - it('should set user input correctly when user provides answers to work_status question', () => { - props = { - ...props, - formValues: { - ...props.formValues, - demographics_work_status: 'other', - demographics_work_status_description: 'test', - }, - }; - - const wrapper = renderer.create(reduxWrapper()).toJSON(); - expect(wrapper).toMatchSnapshot(); - }); - - it('should render ethnicity text correctly', () => { - props = { - ...props, - formValues: { - ...props.formValues, - demographics_user_ethnicity: ['asian'], - }, - }; - - const wrapper = renderer.create(reduxWrapper()).toJSON(); - expect(wrapper).toMatchSnapshot(); - }); - - it('should render ethnicity correctly when multiple options are selected', () => { - props = { - ...props, - formValues: { - ...props.formValues, - demographics_user_ethnicity: ['hispanic-latin-spanish', 'white'], - }, - }; - - const wrapper = renderer.create(reduxWrapper()).toJSON(); - expect(wrapper).toMatchSnapshot(); - }); - - it('should render an Alert when demographicsOptions props are empty', () => { - props = { - ...props, - formValues: { - demographicsOptions: null, - }, - }; - - const wrapper = renderer.create(reduxWrapper()).toJSON(); - expect(wrapper).toMatchSnapshot(); - }); -}); diff --git a/src/account-settings/demographics/test/__snapshots__/DemographicsSection.test.jsx.snap b/src/account-settings/demographics/test/__snapshots__/DemographicsSection.test.jsx.snap deleted file mode 100644 index 1f7c5e98b..000000000 --- a/src/account-settings/demographics/test/__snapshots__/DemographicsSection.test.jsx.snap +++ /dev/null @@ -1,3953 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`DemographicsSection should render 1`] = ` -
    -

    - Optional Information -

    -

    - - Why does localhost collect this information? - - - - - - - in a new tab - - - - -

    -
    -
    -
    -
    -
    -
    - Gender identity -
    - -
    -

    - Prefer not to respond -

    -

    -

    -
    -
    -
    -
    -
    -
    -
    - Race/Ethnicity identity -
    - -
    -

    - -

    -

    -

    -
    -
    -
    -
    -
    -
    -
    - Family income -
    - -
    -

    - Prefer not to respond -

    -

    -

    -
    -
    -
    -
    -
    -
    -
    - U.S. Military status -
    - -
    -

    - Prefer not to respond -

    -

    -

    -
    -
    -
    -
    -
    -
    -
    - Your education level -
    - -
    -

    - Prefer not to respond -

    -

    -

    -
    -
    -
    -
    -
    -
    -
    - Parents/Guardians education level -
    - -
    -

    - Prefer not to respond -

    -

    -

    -
    -
    -
    -
    -
    -
    -
    - Employment status -
    - -
    -

    - Prefer not to respond -

    -

    -

    -
    -
    -
    -
    -
    -
    -
    - Current work industry -
    - -
    -

    - Prefer not to respond -

    -

    -

    -
    -
    -
    -
    -
    -
    -
    - Future work industry -
    - -
    -

    - Prefer not to respond -

    -

    -

    -
    -
    -
    -
    -`; - -exports[`DemographicsSection should render an Alert if an error occurs 1`] = ` -
    -

    - Optional Information -

    -

    - - Why does localhost collect this information? - - - - - - - in a new tab - - - - -

    -
    -
    -
    -
    - An error occurred attempting to retrieve or save your account information. Please try again later. -
    -
    -
    -
    -
    -
    -
    -
    -
    - Gender identity -
    - -
    -

    - Prefer not to respond -

    -

    -

    -
    -
    -
    -
    -
    -
    -
    - Race/Ethnicity identity -
    - -
    -

    - -

    -

    -

    -
    -
    -
    -
    -
    -
    -
    - Family income -
    - -
    -

    - Prefer not to respond -

    -

    -

    -
    -
    -
    -
    -
    -
    -
    - U.S. Military status -
    - -
    -

    - Prefer not to respond -

    -

    -

    -
    -
    -
    -
    -
    -
    -
    - Your education level -
    - -
    -

    - Prefer not to respond -

    -

    -

    -
    -
    -
    -
    -
    -
    -
    - Parents/Guardians education level -
    - -
    -

    - Prefer not to respond -

    -

    -

    -
    -
    -
    -
    -
    -
    -
    - Employment status -
    - -
    -

    - Prefer not to respond -

    -

    -

    -
    -
    -
    -
    -
    -
    -
    - Current work industry -
    - -
    -

    - Prefer not to respond -

    -

    -

    -
    -
    -
    -
    -
    -
    -
    - Future work industry -
    - -
    -

    - Prefer not to respond -

    -

    -

    -
    -
    -
    -
    -`; - -exports[`DemographicsSection should render an Alert when demographicsOptions props are empty 1`] = ` -
    -

    - Optional Information -

    -

    - - Why does localhost collect this information? - - - - - - - in a new tab - - - - -

    -
    -
    -
    -
    - An error occurred attempting to retrieve or save your account information. Please try again later. -
    -
    -
    -
    -`; - -exports[`DemographicsSection should render ethnicity correctly when multiple options are selected 1`] = ` -
    -

    - Optional Information -

    -

    - - Why does localhost collect this information? - - - - - - - in a new tab - - - - -

    -
    -
    -
    -
    -
    -
    - Gender identity -
    - -
    -

    - Prefer not to respond -

    -

    -

    -
    -
    -
    -
    -
    -
    -
    - Race/Ethnicity identity -
    - -
    -

    - Hispanic, Latin, or Spanish origin, White -

    -

    -

    -
    -
    -
    -
    -
    -
    -
    - Family income -
    - -
    -

    - Prefer not to respond -

    -

    -

    -
    -
    -
    -
    -
    -
    -
    - U.S. Military status -
    - -
    -

    - Prefer not to respond -

    -

    -

    -
    -
    -
    -
    -
    -
    -
    - Your education level -
    - -
    -

    - Prefer not to respond -

    -

    -

    -
    -
    -
    -
    -
    -
    -
    - Parents/Guardians education level -
    - -
    -

    - Prefer not to respond -

    -

    -

    -
    -
    -
    -
    -
    -
    -
    - Employment status -
    - -
    -

    - Prefer not to respond -

    -

    -

    -
    -
    -
    -
    -
    -
    -
    - Current work industry -
    - -
    -

    - Prefer not to respond -

    -

    -

    -
    -
    -
    -
    -
    -
    -
    - Future work industry -
    - -
    -

    - Prefer not to respond -

    -

    -

    -
    -
    -
    -
    -`; - -exports[`DemographicsSection should render ethnicity text correctly 1`] = ` -
    -

    - Optional Information -

    -

    - - Why does localhost collect this information? - - - - - - - in a new tab - - - - -

    -
    -
    -
    -
    -
    -
    - Gender identity -
    - -
    -

    - Prefer not to respond -

    -

    -

    -
    -
    -
    -
    -
    -
    -
    - Race/Ethnicity identity -
    - -
    -

    - Asian -

    -

    -

    -
    -
    -
    -
    -
    -
    -
    - Family income -
    - -
    -

    - Prefer not to respond -

    -

    -

    -
    -
    -
    -
    -
    -
    -
    - U.S. Military status -
    - -
    -

    - Prefer not to respond -

    -

    -

    -
    -
    -
    -
    -
    -
    -
    - Your education level -
    - -
    -

    - Prefer not to respond -

    -

    -

    -
    -
    -
    -
    -
    -
    -
    - Parents/Guardians education level -
    - -
    -

    - Prefer not to respond -

    -

    -

    -
    -
    -
    -
    -
    -
    -
    - Employment status -
    - -
    -

    - Prefer not to respond -

    -

    -

    -
    -
    -
    -
    -
    -
    -
    - Current work industry -
    - -
    -

    - Prefer not to respond -

    -

    -

    -
    -
    -
    -
    -
    -
    -
    - Future work industry -
    - -
    -

    - Prefer not to respond -

    -

    -

    -
    -
    -
    -
    -`; - -exports[`DemographicsSection should set user input correctly when user provides answers to work_status question 1`] = ` -
    -

    - Optional Information -

    -

    - - Why does localhost collect this information? - - - - - - - in a new tab - - - - -

    -
    -
    -
    -
    -
    -
    - Gender identity -
    - -
    -

    - Prefer not to respond -

    -

    -

    -
    -
    -
    -
    -
    -
    -
    - Race/Ethnicity identity -
    - -
    -

    - -

    -

    -

    -
    -
    -
    -
    -
    -
    -
    - Family income -
    - -
    -

    - Prefer not to respond -

    -

    -

    -
    -
    -
    -
    -
    -
    -
    - U.S. Military status -
    - -
    -

    - Prefer not to respond -

    -

    -

    -
    -
    -
    -
    -
    -
    -
    - Your education level -
    - -
    -

    - Prefer not to respond -

    -

    -

    -
    -
    -
    -
    -
    -
    -
    - Parents/Guardians education level -
    - -
    -

    - Prefer not to respond -

    -

    -

    -
    -
    -
    -
    -
    -
    -
    - Employment status -
    - -
    -

    - Other: test -

    -

    -

    -
    -
    -
    -
    -
    -
    -
    - Current work industry -
    - -
    -

    - Prefer not to respond -

    -

    -

    -
    -
    -
    -
    -
    -
    -
    - Future work industry -
    - -
    -

    - Prefer not to respond -

    -

    -

    -
    -
    -
    -
    -`; - -exports[`DemographicsSection should set user input correctly when user provides gender self-description 1`] = ` -
    -

    - Optional Information -

    -

    - - Why does localhost collect this information? - - - - - - - in a new tab - - - - -

    -
    -
    -
    -
    -
    -
    - Gender identity -
    - -
    -

    - Prefer to self describe: test -

    -

    -

    -
    -
    -
    -
    -
    -
    -
    - Race/Ethnicity identity -
    - -
    -

    - -

    -

    -

    -
    -
    -
    -
    -
    -
    -
    - Family income -
    - -
    -

    - Prefer not to respond -

    -

    -

    -
    -
    -
    -
    -
    -
    -
    - U.S. Military status -
    - -
    -

    - Prefer not to respond -

    -

    -

    -
    -
    -
    -
    -
    -
    -
    - Your education level -
    - -
    -

    - Prefer not to respond -

    -

    -

    -
    -
    -
    -
    -
    -
    -
    - Parents/Guardians education level -
    - -
    -

    - Prefer not to respond -

    -

    -

    -
    -
    -
    -
    -
    -
    -
    - Employment status -
    - -
    -

    - Prefer not to respond -

    -

    -

    -
    -
    -
    -
    -
    -
    -
    - Current work industry -
    - -
    -

    - Prefer not to respond -

    -

    -

    -
    -
    -
    -
    -
    -
    -
    - Future work industry -
    - -
    -

    - Prefer not to respond -

    -

    -

    -
    -
    -
    -
    -`; diff --git a/src/account-settings/test/JumpNav.test.jsx b/src/account-settings/test/JumpNav.test.jsx index 3eeb07806..b8d4c2d7a 100644 --- a/src/account-settings/test/JumpNav.test.jsx +++ b/src/account-settings/test/JumpNav.test.jsx @@ -11,7 +11,6 @@ const IntlJumpNav = injectIntl(JumpNav); describe('JumpNav', () => { mergeConfig({ - ENABLE_DEMOGRAPHICS_COLLECTION: false, ENABLE_ACCOUNT_DELETION: true, }); @@ -30,7 +29,6 @@ describe('JumpNav', () => { props = { intl: {}, - displayDemographicsLink: false, }; store = configureStore({ notificationPreferences: { @@ -58,13 +56,11 @@ describe('JumpNav', () => { it('should render Optional Information and delete account link', () => { setConfig({ - ENABLE_DEMOGRAPHICS_COLLECTION: true, ENABLE_ACCOUNT_DELETION: true, }); props = { ...props, - displayDemographicsLink: true, }; const tree = renderer.create(( diff --git a/src/account-settings/test/__snapshots__/JumpNav.test.jsx.snap b/src/account-settings/test/__snapshots__/JumpNav.test.jsx.snap index 7a40625e2..6d28aa9dd 100644 --- a/src/account-settings/test/__snapshots__/JumpNav.test.jsx.snap +++ b/src/account-settings/test/__snapshots__/JumpNav.test.jsx.snap @@ -125,19 +125,6 @@ exports[`JumpNav should render Optional Information and delete account link 1`] Profile Information
  • -
  • - - Optional Information - -
  • diff --git a/src/account-settings/test/mockData.js b/src/account-settings/test/mockData.js index c17bd095b..6c102fe08 100644 --- a/src/account-settings/test/mockData.js +++ b/src/account-settings/test/mockData.js @@ -19,10 +19,7 @@ const mockData = { }, ], gender: null, - 'pref-lang': 'en', - shouldDisplayDemographicsSection: false, - demographicsOptions: false, }, errors: {}, confirmationValues: {}, diff --git a/src/index.jsx b/src/index.jsx index 385d7b534..cef8bc4d8 100755 --- a/src/index.jsx +++ b/src/index.jsx @@ -63,8 +63,6 @@ initialize({ config: () => { mergeConfig({ SUPPORT_URL: process.env.SUPPORT_URL, - ENABLE_DEMOGRAPHICS_COLLECTION: (process.env.ENABLE_DEMOGRAPHICS_COLLECTION || false), - DEMOGRAPHICS_BASE_URL: process.env.DEMOGRAPHICS_BASE_URL, SHOW_EMAIL_CHANNEL: process.env.SHOW_EMAIL_CHANNEL || 'false', ENABLE_COPPA_COMPLIANCE: (process.env.ENABLE_COPPA_COMPLIANCE || false), ENABLE_ACCOUNT_DELETION: (process.env.ENABLE_ACCOUNT_DELETION !== 'false'),