Skip to content
Draft
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/MainApp.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { ForgotPasswordPage } from './forgot-password';
import Logistration from './logistration/Logistration';
import { ProgressiveProfiling } from './progressive-profiling';
import { RecommendationsPage } from './recommendations';
import { RegistrationPage } from './register';
import { EmbeddableRegistrationPage } from './register';
import { ResetPasswordPage } from './reset-password';

import './index.scss';
Expand All @@ -41,7 +41,7 @@ const MainApp = () => (
<Route path="/" element={<Navigate replace to={updatePathWithQueryParams(REGISTER_PAGE)} />} />
<Route
path={REGISTER_EMBEDDED_PAGE}
element={<EmbeddedRegistrationRoute><RegistrationPage /></EmbeddedRegistrationRoute>}
element={<EmbeddedRegistrationRoute><EmbeddableRegistrationPage /></EmbeddedRegistrationRoute>}
/>
<Route
path={LOGIN_PAGE}
Expand Down
15 changes: 1 addition & 14 deletions src/common-components/RedirectLogistration.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import { Navigate } from 'react-router-dom';

import {
AUTHN_PROGRESSIVE_PROFILING, RECOMMENDATIONS, REDIRECT,
AUTHN_PROGRESSIVE_PROFILING, RECOMMENDATIONS,
} from '../data/constants';
import { setCookie } from '../data/utils';

Expand All @@ -18,8 +18,6 @@ const RedirectLogistration = (props) => {
redirectToRecommendationsPage,
educationLevel,
userId,
registrationEmbedded,
host,
} = props;
let finalRedirectUrl = '';

Expand All @@ -39,13 +37,6 @@ const RedirectLogistration = (props) => {
// TODO: Do we still need this cookie?
setCookie('van-504-returning-user', true);

if (registrationEmbedded) {
window.parent.postMessage({
action: REDIRECT,
redirectUrl: getConfig().POST_REGISTRATION_REDIRECT_URL,
}, host);
return null;
}
const registrationResult = { redirectUrl: finalRedirectUrl, success };
return (
<Navigate
Expand Down Expand Up @@ -92,8 +83,6 @@ RedirectLogistration.defaultProps = {
optionalFields: {},
redirectToRecommendationsPage: false,
userId: null,
registrationEmbedded: false,
host: '',
};

RedirectLogistration.propTypes = {
Expand All @@ -106,8 +95,6 @@ RedirectLogistration.propTypes = {
optionalFields: PropTypes.shape({}),
redirectToRecommendationsPage: PropTypes.bool,
userId: PropTypes.number,
registrationEmbedded: PropTypes.bool,
host: PropTypes.string,
};

export default RedirectLogistration;
71 changes: 18 additions & 53 deletions src/register/RegistrationPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { getConfig } from '@edx/frontend-platform';
import { sendPageEvent, sendTrackEvent } from '@edx/frontend-platform/analytics';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Form, Spinner, StatefulButton } from '@edx/paragon';
import classNames from 'classnames';
import PropTypes from 'prop-types';
import { Helmet } from 'react-helmet';
import Skeleton from 'react-loading-skeleton';
Expand Down Expand Up @@ -37,7 +36,7 @@ import {
COMPLETE_STATE, PENDING_STATE, REGISTER_PAGE,
} from '../data/constants';
import {
getAllPossibleQueryParams, getTpaHint, getTpaProvider, isHostAvailableInQueryParams, setCookie,
getAllPossibleQueryParams, getTpaHint, getTpaProvider, setCookie,
} from '../data/utils';

/**
Expand All @@ -47,7 +46,6 @@ const RegistrationPage = (props) => {
const { formatMessage } = useIntl();
const dispatch = useDispatch();

const registrationEmbedded = isHostAvailableInQueryParams();
const platformName = getConfig().SITE_NAME;
const flags = {
showConfigurableEdxFields: getConfig().SHOW_CONFIGURABLE_EDX_FIELDS,
Expand Down Expand Up @@ -99,13 +97,6 @@ const RegistrationPage = (props) => {
const [errors, setErrors] = useState({ ...backedUpFormData.errors });
const [errorCode, setErrorCode] = useState({ type: '', count: 0 });
const [formStartTime, setFormStartTime] = useState(null);
// temporary error state for embedded experience because we don't want to show errors on blur
const [temporaryErrors, setTemporaryErrors] = useState({ ...backedUpFormData.errors });

const { cta, host } = queryParams;
const buttonLabel = cta
? formatMessage(messages['create.account.cta.button'], { label: cta })
: formatMessage(messages['create.account.for.free.button']);

/**
* Set the userPipelineDetails data in formFields for only first time
Expand Down Expand Up @@ -156,13 +147,9 @@ const RegistrationPage = (props) => {

useEffect(() => {
if (backendValidations) {
if (registrationEmbedded) {
setTemporaryErrors(prevErrors => ({ ...prevErrors, ...backendValidations }));
} else {
setErrors(prevErrors => ({ ...prevErrors, ...backendValidations }));
}
setErrors(prevErrors => ({ ...prevErrors, ...backendValidations }));
}
}, [backendValidations, registrationEmbedded]);
}, [backendValidations]);

useEffect(() => {
if (registrationErrorCode) {
Expand Down Expand Up @@ -206,23 +193,10 @@ const RegistrationPage = (props) => {
};

const handleErrorChange = (fieldName, error) => {
if (registrationEmbedded) {
setTemporaryErrors(prevErrors => ({
...prevErrors,
[fieldName]: error,
}));
if (error === '' && errors[fieldName] !== '') {
setErrors(prevErrors => ({
...prevErrors,
[fieldName]: error,
}));
}
} else {
setErrors(prevErrors => ({
...prevErrors,
[fieldName]: error,
}));
}
setErrors(prevErrors => ({
...prevErrors,
[fieldName]: error,
}));
};

const registerUser = () => {
Expand All @@ -237,7 +211,7 @@ const RegistrationPage = (props) => {
// Validating form data before submitting
const { isValid, fieldErrors } = isFormValid(
payload,
registrationEmbedded ? temporaryErrors : errors,
errors,
configurableFormFields,
fieldDescriptions,
formatMessage,
Expand Down Expand Up @@ -288,13 +262,11 @@ const RegistrationPage = (props) => {
<title>{formatMessage(messages['register.page.title'], { siteName: getConfig().SITE_NAME })}</title>
</Helmet>
<RedirectLogistration
host={host}
authenticatedUser={registrationResult.authenticatedUser}
success={registrationResult.success}
redirectUrl={registrationResult.redirectUrl}
finishAuthUrl={finishAuthUrl}
optionalFields={optionalFields}
registrationEmbedded={registrationEmbedded}
redirectToProgressiveProfilingPage={
getConfig().ENABLE_PROGRESSIVE_PROFILING_ON_AUTHN && !!Object.keys(optionalFields.fields).length
}
Expand All @@ -304,12 +276,7 @@ const RegistrationPage = (props) => {
<Spinner animation="border" variant="primary" id="tpa-spinner" />
</div>
) : (
<div
className={classNames(
'mw-xs mt-3',
{ 'w-100 m-auto pt-4 main-content': registrationEmbedded },
)}
>
<div className="mw-xs mt-3">
<ThirdPartyAuthAlert
currentProvider={currentProvider}
platformName={platformName}
Expand Down Expand Up @@ -365,7 +332,7 @@ const RegistrationPage = (props) => {
email={formFields.email}
fieldErrors={errors}
formFields={configurableFormFields}
setFieldErrors={registrationEmbedded ? setTemporaryErrors : setErrors}
setFieldErrors={setErrors}
setFormFields={setConfigurableFormFields}
autoSubmitRegisterForm={autoSubmitRegForm}
fieldDescriptions={fieldDescriptions}
Expand All @@ -378,21 +345,19 @@ const RegistrationPage = (props) => {
className="register-button mt-4 mb-4"
state={submitState}
labels={{
default: buttonLabel,
default: formatMessage(messages['create.account.for.free.button']),
pending: '',
}}
onClick={handleSubmit}
onMouseDown={(e) => e.preventDefault()}
/>
{!registrationEmbedded && (
<ThirdPartyAuth
currentProvider={currentProvider}
providers={providers}
secondaryProviders={secondaryProviders}
handleInstitutionLogin={handleInstitutionLogin}
thirdPartyAuthApiStatus={thirdPartyAuthApiStatus}
/>
)}
<ThirdPartyAuth
currentProvider={currentProvider}
providers={providers}
secondaryProviders={secondaryProviders}
handleInstitutionLogin={handleInstitutionLogin}
thirdPartyAuthApiStatus={thirdPartyAuthApiStatus}
/>
</Form>
</div>
)}
Expand Down
98 changes: 0 additions & 98 deletions src/register/RegistrationPage.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -503,14 +503,6 @@ describe('RegistrationPage', () => {
expect(registrationPage.find('.institutions__heading').text()).toEqual('Register with institution/campus credentials');
});

it('should show button label based on cta query params value', () => {
const buttonLabel = 'Register';
delete window.location;
window.location = { href: getConfig().BASE_URL, search: `?cta=${buttonLabel}` };
const registrationPage = mount(reduxWrapper(<IntlRegistrationPage {...props} />));
expect(registrationPage.find('button[type="submit"] span').first().text()).toEqual(buttonLabel);
});

it('should not display password field when current provider is present', () => {
store = mockStore({
...initialState,
Expand Down Expand Up @@ -892,96 +884,6 @@ describe('RegistrationPage', () => {
expect(registrationPage.find('.email-suggestion-alert-warning').first().text()).toEqual('john.doe@hotmail.com');
});

// ********* Embedded experience tests *********/

it('should call the postMessage API when embedded variant is rendered', () => {
getLocale.mockImplementation(() => ('en-us'));
mergeConfig({
ENABLE_PROGRESSIVE_PROFILING_ON_AUTHN: true,
});

window.parent.postMessage = jest.fn();

delete window.location;
window.location = { href: getConfig().BASE_URL.concat(AUTHN_PROGRESSIVE_PROFILING), search: '?host=http://localhost/host-website' };

store = mockStore({
...initialState,
register: {
...initialState.register,
registrationResult: {
success: true,
},
},
commonComponents: {
...initialState.commonComponents,
optionalFields: {
extended_profile: {},
fields: {
level_of_education: { name: 'level_of_education', error_message: false },
},
},
},
});
const progressiveProfilingPage = mount(reduxWrapper(
<IntlRegistrationPage {...props} />,
));
progressiveProfilingPage.update();
expect(window.parent.postMessage).toHaveBeenCalledTimes(2);
});

it('should not display validations error on blur event when embedded variant is rendered', () => {
delete window.location;
window.location = { href: getConfig().BASE_URL.concat(REGISTER_PAGE), search: '?host=http://localhost/host-website' };
const registrationPage = mount(reduxWrapper(<IntlRegistrationPage {...props} />));

registrationPage.find('input#username').simulate('blur', { target: { value: '', name: 'username' } });
expect(registrationPage.find('div[feedback-for="username"]').exists()).toBeFalsy();

registrationPage.find('input[name="country"]').simulate('blur', { target: { value: '', name: 'country' } });
expect(registrationPage.find('div[feedback-for="country"]').exists()).toBeFalsy();
});

it('should set errors in temporary state when validations are returned by registration api', () => {
delete window.location;
window.location = { href: getConfig().BASE_URL.concat(REGISTER_PAGE), search: '?host=http://localhost/host-website' };

const usernameError = 'It looks like this username is already taken';
const emailError = 'This email is already associated with an existing or previous account';
store = mockStore({
...initialState,
register: {
...initialState.register,
registrationError: {
username: [{ userMessage: usernameError }],
email: [{ userMessage: emailError }],
},
},
});
const registrationPage = mount(routerWrapper(reduxWrapper(
<IntlRegistrationPage {...props} />),
)).find('RegistrationPage');

expect(registrationPage.find('div[feedback-for="username"]').exists()).toBeFalsy();
expect(registrationPage.find('div[feedback-for="email"]').exists()).toBeFalsy();
});

it('should clear error on focus for embedded experience also', () => {
delete window.location;
window.location = {
href: getConfig().BASE_URL.concat(REGISTER_PAGE),
search: '?host=http://localhost/host-website',
};

const registrationPage = mount(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
registrationPage.find('button.btn-brand').simulate('click');

expect(registrationPage.find('div[feedback-for="password"]').text()).toContain(emptyFieldValidation.password);

registrationPage.find('input#password').simulate('focus');
expect(registrationPage.find('div[feedback-for="password"]').exists()).toBeFalsy();
});

it('should show spinner instead of form while registering if autoSubmitRegForm is true', () => {
jest.spyOn(global.Date, 'now').mockImplementation(() => 0);
getLocale.mockImplementation(() => ('en-us'));
Expand Down
Loading