From 9b046146a0e031fcc7ac48d5ccef27d9eaeed15e Mon Sep 17 00:00:00 2001 From: Syed Sajjad Hussain Shah <52817156+syedsajjadkazmii@users.noreply.github.com> Date: Tue, 27 Feb 2024 10:12:16 +0500 Subject: [PATCH] fix: fix simplify registration experiment bugs (#1175) --- src/register/RegistrationPage.jsx | 31 +++++++++------ .../data/optimizelyExperiment/helper.js | 39 ++++++++++++++++--- ...implifyRegistrationExperimentVariation.jsx | 4 +- 3 files changed, 55 insertions(+), 19 deletions(-) diff --git a/src/register/RegistrationPage.jsx b/src/register/RegistrationPage.jsx index 02987397..c99cbd13 100644 --- a/src/register/RegistrationPage.jsx +++ b/src/register/RegistrationPage.jsx @@ -29,6 +29,7 @@ import { import { FIRST_STEP, getRegisterButtonLabelInExperiment, + NOT_INITIALIZED, prepareSimplifiedRegistrationFirstStepPayload, SECOND_STEP, shouldDisplayFieldInExperiment, @@ -219,10 +220,18 @@ const RegistrationPage = (props) => { useEffect(() => { if (registrationResult.success) { // This event is used by GTM - sendTrackEvent('edx.bi.user.account.registered.client', { - variation: simplifyRegistrationExpVariation, - picked_suggested_username: usernameSuggestionsBackup.includes(registrationResult?.authenticatedUser?.username), - }); + let registeredEventProps = {}; + + if (simplifyRegistrationExpVariation !== NOT_INITIALIZED) { + registeredEventProps = { + variation: simplifyRegistrationExpVariation, + picked_suggested_username: usernameSuggestionsBackup.includes( + registrationResult?.authenticatedUser?.username, + ), + }; + } + + sendTrackEvent('edx.bi.user.account.registered.client', registeredEventProps); // This is used by the "User Retention Rate Event" on GTM setCookie(getConfig().USER_RETENTION_COOKIE_NAME, true); @@ -302,15 +311,9 @@ const RegistrationPage = (props) => { if (simplifyRegistrationExpVariation === SIMPLIFIED_REGISTRATION_VARIATION && simplifiedRegisterPageStep === FIRST_STEP) { trackSimplifyRegistrationContinueBtnClicked(); - const payload = prepareSimplifiedRegistrationFirstStepPayload( - formFields, - configurableFormFields, + const { isValid, fieldErrors } = validateSimplifiedRegistrationFirstStepPayload( + formFields, errors, configurableFormFields, fieldDescriptions, formatMessage, ); - const { - isValid, - fieldErrors, - } = validateSimplifiedRegistrationFirstStepPayload(payload, errors, formatMessage); - setErrors(prevErrors => ({ ...prevErrors, ...fieldErrors, @@ -319,6 +322,10 @@ const RegistrationPage = (props) => { if (!isValid) { setErrorCode(prevState => ({ type: FORM_SUBMISSION_ERROR, count: prevState.count + 1 })); } else { + const payload = prepareSimplifiedRegistrationFirstStepPayload( + formFields, + configurableFormFields, + ); dispatch(fetchRealtimeValidations(payload, true)); } } else { diff --git a/src/register/data/optimizelyExperiment/helper.js b/src/register/data/optimizelyExperiment/helper.js index 9d7600dc..22a586a2 100644 --- a/src/register/data/optimizelyExperiment/helper.js +++ b/src/register/data/optimizelyExperiment/helper.js @@ -6,6 +6,7 @@ import { getConfig, snakeCaseObject } from '@edx/frontend-platform'; import messages from '../../messages'; import { validatePasswordField } from '../utils'; +export const NOT_INITIALIZED = 'experiment-not-initialized'; export const DEFAULT_VARIATION = 'default-register-page'; export const SIMPLIFIED_REGISTRATION_VARIATION = 'simplified-register-page'; @@ -41,7 +42,8 @@ export function activateSimplifyRegistrationExperiment() { * registration page experiment */ export const shouldDisplayFieldInExperiment = (fieldName, expVariation, registerPageStep) => ( - !expVariation || expVariation === DEFAULT_VARIATION || (expVariation === SIMPLIFIED_REGISTRATION_VARIATION + !expVariation || expVariation === NOT_INITIALIZED || expVariation === DEFAULT_VARIATION + || (expVariation === SIMPLIFIED_REGISTRATION_VARIATION && ( (registerPageStep === FIRST_STEP && fieldName !== 'username') || (registerPageStep === SECOND_STEP && SIMPLIFIED_REGISTER_PAGE_SECOND_STEP_FIELDS.includes(fieldName)) @@ -80,15 +82,22 @@ export const prepareSimplifiedRegistrationFirstStepPayload = ( return payload; }; -export const validateSimplifiedRegistrationFirstStepPayload = (payload, errors, formatMessage) => { +export const validateSimplifiedRegistrationFirstStepPayload = ( + payload, errors, configurableFormFields, fieldDescriptions, formatMessage, +) => { const fieldErrors = { ...errors }; let isValid = true; - Object.keys(payload).forEach(key => { + + // We dont want to validate username since it is in second step of registration + const fieldsPayload = { ...payload }; + delete fieldsPayload.username; + + Object.keys(fieldsPayload).forEach(key => { if (key === 'password') { // We need to explicitly validated password field because the validations for password value // are different at frontend and backend. - fieldErrors[key] = validatePasswordField(payload[key], formatMessage); - } else if (!payload[key]) { + fieldErrors[key] = validatePasswordField(fieldsPayload[key], formatMessage); + } else if (!fieldsPayload[key]) { fieldErrors[key] = formatMessage(messages[`empty.${key}.field.error`]); } if (fieldErrors[key]) { @@ -96,5 +105,25 @@ export const validateSimplifiedRegistrationFirstStepPayload = (payload, errors, } }); + // Don't validate when country field is optional or hidden and not present on registration form + if (configurableFormFields?.country && !configurableFormFields.country?.displayValue) { + fieldErrors.country = formatMessage(messages['empty.country.field.error']); + isValid = false; + } else if (configurableFormFields?.country && !configurableFormFields.country?.countryCode) { + fieldErrors.country = formatMessage(messages['invalid.country.field.error']); + isValid = false; + } + + Object.keys(fieldDescriptions).forEach(key => { + if (key === 'country' && !configurableFormFields.country.displayValue) { + fieldErrors[key] = formatMessage(messages['empty.country.field.error']); + } else if (!configurableFormFields[key]) { + fieldErrors[key] = fieldDescriptions[key].error_message; + } + if (fieldErrors[key]) { + isValid = false; + } + }); + return { isValid, fieldErrors }; }; diff --git a/src/register/data/optimizelyExperiment/useSimplifyRegistrationExperimentVariation.jsx b/src/register/data/optimizelyExperiment/useSimplifyRegistrationExperimentVariation.jsx index 1cd42f41..5f801b87 100644 --- a/src/register/data/optimizelyExperiment/useSimplifyRegistrationExperimentVariation.jsx +++ b/src/register/data/optimizelyExperiment/useSimplifyRegistrationExperimentVariation.jsx @@ -2,8 +2,8 @@ import { useEffect, useState } from 'react'; import { activateSimplifyRegistrationExperiment, - DEFAULT_VARIATION, getSimplifyRegistrationExperimentVariation, + NOT_INITIALIZED, } from './helper'; import { trackSimplifyRegistrationFirstStepViewed } from './track'; import { COMPLETE_STATE } from '../../../data/constants'; @@ -35,7 +35,7 @@ const useSimplifyRegistrationExperimentVariation = ( } else { // This is to handle the case when user dont get variation for some reason, the register page // shows unlimited spinner. - setVariation(DEFAULT_VARIATION); + setVariation(NOT_INITIALIZED); } };