diff --git a/src/common-components/data/reducers.js b/src/common-components/data/reducers.js index 7b449540..396631e1 100644 --- a/src/common-components/data/reducers.js +++ b/src/common-components/data/reducers.js @@ -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, }, }; diff --git a/src/progressive-profiling/ProgressiveProfiling.jsx b/src/progressive-profiling/ProgressiveProfiling.jsx index c0794302..d8296f50 100644 --- a/src/progressive-profiling/ProgressiveProfiling.jsx +++ b/src/progressive-profiling/ProgressiveProfiling.jsx @@ -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) => { - {queryParams?.next && ( + {(props.shouldRedirect && welcomePageContext.nextUrl) && ( )} {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, }; }; diff --git a/src/progressive-profiling/data/selectors.js b/src/progressive-profiling/data/selectors.js new file mode 100644 index 00000000..697bcfa8 --- /dev/null +++ b/src/progressive-profiling/data/selectors.js @@ -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, + }), +); diff --git a/src/progressive-profiling/tests/ProgressiveProfiling.test.jsx b/src/progressive-profiling/tests/ProgressiveProfiling.test.jsx index 83040d4c..01b7a13e 100644 --- a/src/progressive-profiling/tests/ProgressiveProfiling.test.jsx +++ b/src/progressive-profiling/tests/ProgressiveProfiling.test.jsx @@ -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, }, });