feat: param based redirection (#993)
On welcome page CTA click redirection would be based on next query param. VAN-1535
This commit is contained in:
@@ -3,7 +3,10 @@ import { COMPLETE_STATE, FAILURE_STATE, PENDING_STATE } from '../../data/constan
|
||||
|
||||
export const defaultState = {
|
||||
fieldDescriptions: {},
|
||||
optionalFields: {},
|
||||
optionalFields: {
|
||||
fields: {},
|
||||
extended_profile: [],
|
||||
},
|
||||
thirdPartyAuthApiStatus: null,
|
||||
thirdPartyAuthContext: {
|
||||
currentProvider: null,
|
||||
@@ -13,6 +16,7 @@ export const defaultState = {
|
||||
secondaryProviders: [],
|
||||
pipelineUserDetails: null,
|
||||
errorMessage: null,
|
||||
welcomePageRedirectUrl: null,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -23,12 +23,12 @@ import PropTypes from 'prop-types';
|
||||
import { Helmet } from 'react-helmet';
|
||||
|
||||
import { saveUserProfile } from './data/actions';
|
||||
import { welcomePageContextSelector } from './data/selectors';
|
||||
import messages from './messages';
|
||||
import ProgressiveProfilingPageModal from './ProgressiveProfilingPageModal';
|
||||
import BaseContainer from '../base-container';
|
||||
import { RedirectLogistration } from '../common-components';
|
||||
import { getThirdPartyAuthContext } from '../common-components/data/actions';
|
||||
import { optionalFieldsSelector } from '../common-components/data/selectors';
|
||||
import {
|
||||
COMPLETE_STATE,
|
||||
DEFAULT_REDIRECT_URL,
|
||||
@@ -55,6 +55,7 @@ const ProgressiveProfiling = (props) => {
|
||||
} = props;
|
||||
const registrationEmbedded = isHostAvailableInQueryParams();
|
||||
|
||||
const queryParams = getAllPossibleQueryParams();
|
||||
const authenticatedUser = getAuthenticatedUser();
|
||||
const DASHBOARD_URL = getConfig().LMS_BASE_URL.concat(DEFAULT_REDIRECT_URL);
|
||||
const enablePersonalizedRecommendations = getConfig().ENABLE_PERSONALIZED_RECOMMENDATIONS;
|
||||
@@ -90,9 +91,9 @@ const ProgressiveProfiling = (props) => {
|
||||
|
||||
useEffect(() => {
|
||||
if (registrationEmbedded) {
|
||||
getFieldDataFromBackend({ is_welcome_page: true });
|
||||
getFieldDataFromBackend({ is_welcome_page: true, next: queryParams?.next });
|
||||
}
|
||||
}, [registrationEmbedded, getFieldDataFromBackend]);
|
||||
}, [registrationEmbedded, getFieldDataFromBackend, queryParams?.next]);
|
||||
|
||||
useEffect(() => {
|
||||
if (registrationEmbedded && Object.keys(welcomePageContext).includes('fields')) {
|
||||
@@ -100,7 +101,8 @@ const ProgressiveProfiling = (props) => {
|
||||
fields: welcomePageContext.fields,
|
||||
extendedProfile: welcomePageContext.extended_profile,
|
||||
});
|
||||
setRegistrationResult({ redirectUrl: getConfig().SEARCH_CATALOG_URL });
|
||||
const nextUrl = welcomePageContext.nextUrl ? welcomePageContext.nextUrl : getConfig().SEARCH_CATALOG_URL;
|
||||
setRegistrationResult({ redirectUrl: nextUrl });
|
||||
}
|
||||
}, [registrationEmbedded, welcomePageContext]);
|
||||
|
||||
@@ -142,8 +144,6 @@ const ProgressiveProfiling = (props) => {
|
||||
return null;
|
||||
}
|
||||
|
||||
const queryParams = getAllPossibleQueryParams();
|
||||
|
||||
const handleSubmit = (e) => {
|
||||
e.preventDefault();
|
||||
window.history.replaceState(location.state, null, '');
|
||||
@@ -210,10 +210,10 @@ const ProgressiveProfiling = (props) => {
|
||||
</title>
|
||||
</Helmet>
|
||||
<ProgressiveProfilingPageModal isOpen={showModal} redirectUrl={registrationResult.redirectUrl} />
|
||||
{queryParams?.next && (
|
||||
{(props.shouldRedirect && welcomePageContext.nextUrl) && (
|
||||
<RedirectLogistration
|
||||
success
|
||||
redirectUrl={queryParams.next}
|
||||
redirectUrl={registrationResult.redirectUrl}
|
||||
/>
|
||||
)}
|
||||
{props.shouldRedirect && (
|
||||
@@ -300,6 +300,7 @@ ProgressiveProfiling.propTypes = {
|
||||
welcomePageContext: PropTypes.shape({
|
||||
extended_profile: PropTypes.arrayOf(PropTypes.string),
|
||||
fields: PropTypes.shape({}),
|
||||
nextUrl: PropTypes.string,
|
||||
}),
|
||||
welcomePageContextApiStatus: PropTypes.string,
|
||||
// Actions
|
||||
@@ -323,7 +324,7 @@ const mapStateToProps = state => {
|
||||
shouldRedirect: welcomePageStore.success,
|
||||
showError: welcomePageStore.showError,
|
||||
submitState: welcomePageStore.submitState,
|
||||
welcomePageContext: optionalFieldsSelector(state),
|
||||
welcomePageContext: welcomePageContextSelector(state),
|
||||
welcomePageContextApiStatus: state.commonComponents.thirdPartyAuthApiStatus,
|
||||
};
|
||||
};
|
||||
|
||||
14
src/progressive-profiling/data/selectors.js
Normal file
14
src/progressive-profiling/data/selectors.js
Normal file
@@ -0,0 +1,14 @@
|
||||
import { createSelector } from 'reselect';
|
||||
|
||||
export const storeName = 'commonComponents';
|
||||
|
||||
export const commonComponentsSelector = state => ({ ...state[storeName] });
|
||||
|
||||
export const welcomePageContextSelector = createSelector(
|
||||
commonComponentsSelector,
|
||||
commonComponents => ({
|
||||
fields: commonComponents.optionalFields.fields,
|
||||
extended_profile: commonComponents.optionalFields.extended_profile,
|
||||
nextUrl: commonComponents.thirdPartyAuthContext.welcomePageRedirectUrl,
|
||||
}),
|
||||
);
|
||||
@@ -70,6 +70,9 @@ describe('ProgressiveProfilingTests', () => {
|
||||
commonComponents: {
|
||||
thirdPartyAuthApiStatus: null,
|
||||
optionalFields: {},
|
||||
thirdPartyAuthContext: {
|
||||
welcomePageRedirectUrl: null,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -156,21 +159,6 @@ describe('ProgressiveProfilingTests', () => {
|
||||
expect(store.dispatch).toHaveBeenCalledWith(saveUserProfile('abc123', formPayload));
|
||||
});
|
||||
|
||||
it('should set host property value to host where iframe is embedded for on ramp experience', async () => {
|
||||
getAuthenticatedUser.mockReturnValue({ userId: 3, username: 'abc123' });
|
||||
const expectedEventProperties = {
|
||||
isGenderSelected: false,
|
||||
isYearOfBirthSelected: false,
|
||||
isLevelOfEducationSelected: false,
|
||||
host: 'http://example.com',
|
||||
};
|
||||
delete window.location;
|
||||
window.location = { href: getConfig().BASE_URL.concat(AUTHN_PROGRESSIVE_PROFILING), search: '?host=http://example.com' };
|
||||
const progressiveProfilingPage = await getProgressiveProfilingPage();
|
||||
progressiveProfilingPage.find('button.btn-brand').simulate('click');
|
||||
expect(sendTrackEvent).toHaveBeenCalledWith('edx.bi.welcome.page.submit.clicked', expectedEventProperties);
|
||||
});
|
||||
|
||||
it('should set host property value empty for non-embedded experience', async () => {
|
||||
getAuthenticatedUser.mockReturnValue({ userId: 3, username: 'abc123' });
|
||||
const expectedEventProperties = {
|
||||
@@ -186,17 +174,6 @@ describe('ProgressiveProfilingTests', () => {
|
||||
expect(sendTrackEvent).toHaveBeenCalledWith('edx.bi.welcome.page.submit.clicked', expectedEventProperties);
|
||||
});
|
||||
|
||||
it('should set host property value embedded host for on ramp experience for skip link event', async () => {
|
||||
getAuthenticatedUser.mockReturnValue({ userId: 3, username: 'abc123' });
|
||||
const host = 'http://example.com';
|
||||
delete window.location;
|
||||
window.location = { href: getConfig().BASE_URL.concat(AUTHN_PROGRESSIVE_PROFILING), search: `?host=${host}` };
|
||||
const progressiveProfilingPage = await getProgressiveProfilingPage();
|
||||
|
||||
progressiveProfilingPage.find('button.btn-link').simulate('click');
|
||||
expect(sendTrackEvent).toHaveBeenCalledWith('edx.bi.welcome.page.skip.link.clicked', { host });
|
||||
});
|
||||
|
||||
it('should open modal on pressing skip for now button', async () => {
|
||||
getAuthenticatedUser.mockReturnValue({ userId: 3, username: 'abc123' });
|
||||
delete window.location;
|
||||
@@ -283,21 +260,9 @@ describe('ProgressiveProfilingTests', () => {
|
||||
mergeConfig({
|
||||
SEARCH_CATALOG_URL: 'http://localhost/search',
|
||||
});
|
||||
const host = 'http://example.com';
|
||||
|
||||
delete window.location;
|
||||
window.location = {
|
||||
assign: jest.fn().mockImplementation((value) => { window.location.href = value; }),
|
||||
href: getConfig().BASE_URL,
|
||||
search: `?variant=${EMBEDDED}`,
|
||||
};
|
||||
|
||||
it('should render fields returned by backend API', async () => {
|
||||
delete window.location;
|
||||
window.location = {
|
||||
assign: jest.fn().mockImplementation((value) => { window.location.href = value; }),
|
||||
href: getConfig().BASE_URL,
|
||||
search: `?variant=${EMBEDDED}&host=http://localhost/host-website`,
|
||||
};
|
||||
beforeEach(() => {
|
||||
props = {};
|
||||
store = mockStore({
|
||||
...initialState,
|
||||
@@ -307,6 +272,44 @@ describe('ProgressiveProfilingTests', () => {
|
||||
optionalFields,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should set host property value embedded host for on ramp experience for skip link event', async () => {
|
||||
delete window.location;
|
||||
window.location = {
|
||||
href: getConfig().BASE_URL.concat(AUTHN_PROGRESSIVE_PROFILING),
|
||||
search: `?host=${host}&variant=${EMBEDDED}`,
|
||||
};
|
||||
const progressiveProfilingPage = await getProgressiveProfilingPage();
|
||||
|
||||
progressiveProfilingPage.find('button.btn-link').simulate('click');
|
||||
expect(sendTrackEvent).toHaveBeenCalledWith('edx.bi.welcome.page.skip.link.clicked', { host });
|
||||
});
|
||||
|
||||
it('should set host property value to host where iframe is embedded for on ramp experience', async () => {
|
||||
const expectedEventProperties = {
|
||||
isGenderSelected: false,
|
||||
isYearOfBirthSelected: false,
|
||||
isLevelOfEducationSelected: false,
|
||||
host: 'http://example.com',
|
||||
};
|
||||
delete window.location;
|
||||
window.location = {
|
||||
href: getConfig().BASE_URL.concat(AUTHN_PROGRESSIVE_PROFILING),
|
||||
search: `?host=${host}`,
|
||||
};
|
||||
const progressiveProfilingPage = await getProgressiveProfilingPage();
|
||||
progressiveProfilingPage.find('button.btn-brand').simulate('click');
|
||||
expect(sendTrackEvent).toHaveBeenCalledWith('edx.bi.welcome.page.submit.clicked', expectedEventProperties);
|
||||
});
|
||||
|
||||
it('should render fields returned by backend API', async () => {
|
||||
delete window.location;
|
||||
window.location = {
|
||||
assign: jest.fn().mockImplementation((value) => { window.location.href = value; }),
|
||||
href: getConfig().BASE_URL,
|
||||
search: `?variant=${EMBEDDED}&host=${host}`,
|
||||
};
|
||||
|
||||
const progressiveProfilingPage = await getProgressiveProfilingPage();
|
||||
expect(progressiveProfilingPage.find('#gender').exists()).toBeTruthy();
|
||||
@@ -319,7 +322,6 @@ describe('ProgressiveProfilingTests', () => {
|
||||
href: getConfig().BASE_URL,
|
||||
search: `?variant=${EMBEDDED}`,
|
||||
};
|
||||
props = {};
|
||||
store = mockStore({
|
||||
...initialState,
|
||||
commonComponents: {
|
||||
@@ -338,7 +340,7 @@ describe('ProgressiveProfilingTests', () => {
|
||||
window.location = {
|
||||
assign: jest.fn().mockImplementation((value) => { window.location.href = value; }),
|
||||
href: getConfig().BASE_URL,
|
||||
search: `?variant=${EMBEDDED}&host=http://localhost/host-website&next=${redirectUrl}`,
|
||||
search: `?variant=${EMBEDDED}&host=${host}&next=${redirectUrl}`,
|
||||
};
|
||||
props = {};
|
||||
store = mockStore({
|
||||
@@ -347,6 +349,13 @@ describe('ProgressiveProfilingTests', () => {
|
||||
...initialState.commonComponents,
|
||||
thirdPartyAuthApiStatus: COMPLETE_STATE,
|
||||
optionalFields,
|
||||
thirdPartyAuthContext: {
|
||||
welcomePageRedirectUrl: redirectUrl,
|
||||
},
|
||||
},
|
||||
welcomePage: {
|
||||
...initialState.welcomePage,
|
||||
success: true,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user